Keeping your scripts structured with procedures is great for organization and flexibility—but show caution in their use.
        
        Get Yourself Organized, Part 2
        Keeping your scripts structured with procedures is great for organization and flexibility—but show caution in their use.
        
        
			- By Chris Brooke
- August 01, 2000
If you promise not to tell anyone, I’ll let you in on 
        a little secret: I’m not very organized. My desk has stacks 
        upon stacks of papers that I’m sure must be important 
        for something, I simply can’t remember what. Sure, if 
        anyone asks, I maintain that I have a unique filing system 
        and that I know where everything is. Truth is, it ain’t 
        so. Usually I’m lucky enough to find what I’m looking 
        for in the nick of time, but it’s just that: luck. How 
        is it, then, that I’m able to keep my scripts so organized? 
        Well, many years ago, after wading through pages and pages 
        of spaghetti code, I finally came to the realization that 
        I’d never get any scripts completed and debugged unless 
        I did a better job of organizing them. Procedures to the 
        rescue! Now, if I could just figure out a procedure for 
        finding my phone underneath one of these piles I might 
        be able to call my boss and tell him not to open that 
        “ILoveYou” email. 
      Last month, 
        we looked at how procedures (Subs and Functions) are able 
        to keep track of variables and components declared locally. 
        The most significant advantage to using procedures along 
        with locally-declared variables (aside from organization) 
        is reusability. So long as the procedure doesn’t rely 
        on any externally-declared variables, you can use it anywhere! 
        Let’s start by examining my solution to the homework I 
        assigned last month. 
      The Assignment: Write 
        a script to compare the “Date Last Modified” property 
        of two different files, using only one object. 
      The Solution: Simplicity 
        is its own reward…
      ' DateComp.vbs
        ' Compare DateLastModified property of two
        ' files using procedures 
      Option Explicit 
      Dim strFile1, strFile2 
      Main 
        WScript.Quit 
      Sub Main() 
          strFile1=GetFile("First") 
          strFile2=GetFile("Second")
            If GetModDate(strFile1)=Empty 
        OR 
              GetModDate(strFile2)= 
        Empty Then Wscript.Quit 
            If GetModDate(strFile1)> GetModDate(strFile2) 
        
              Then WScript.Echo 
        strFile1 
              & "was modified 
        most recently."
            Elseif GetModDate(strFile1)< getmoddate(strfile2)="">
              WScript.Echo strFile2 
        
              & " was modified most 
        recently."
            End If 
        End Sub 
      Function GetFile(File) 
          GetFile=InputBox(
          "Enter the complete path and name of the " 
        
          & File & " file:", "Enter FileName") 
        
        End Function 
      Function GetModDate(strFile) 
          Dim objFSO, objFile 
          Set objFSO=CreateObject("Scripting.FileSystemObject") 
        
            If objFSO.FileExists(strFile) 
        Then 
              Set objFile=objFSO.GetFile(strFile) 
              GetModDate=objFile.DateLastModified 
        
            Else 
              GetModDate=Empty 
            End If 
        End Function 
      The only procedure that creates and uses the FileSystemObject 
        is the “GetModDate” function. By declaring the variables 
        and creating the objects inside the function, we can put 
        this routine in any script and be assured that we won’t 
        “step on” any variables or objects created elsewhere in 
        the script. Of course, we can add code to handle Empty 
        strings more elegantly than simply exiting the script, 
        but that’s the easy part. We’ve already learned how to 
        do that! 
      Don’t Overdo It!
      I think now is as good a time as any to remind you to 
        be mindful of your resources. Objects, whether they’re 
        built-in Windows components or third-party tools, require 
        a certain amount of overhead. When you instantiate (CreateObject) 
        a component, it’s like assigning a value to a variable—a 
        potentially huge value! If you go off creating tons of 
        objects willy-nilly, you just might see your performance 
        dropping off. 
      As with all things, there’s a balance to be achieved 
        between maximum flexibility and maximum performance. While 
        keeping your scripts structured with procedures is great 
        for organization and flexibility, too many instantiations 
        of too many components can make your super-duper Pentium 
        III seem like a 486! If you find this happening to you, 
        here are some tips you can use in a pinch to get back 
        that performance edge. 
      First, go through your script and trim out all of the 
        “extra instantiations” that you can. If you’re using one 
        or two objects throughout your script, consider declaring 
        it in the main body, instead of inside procedures. You’ll 
        lose some of the reusability but gain back lost performance. 
        I know, this is completely contrary to what I just demonstrated 
        in the above script. Remember, that was to show you how 
        to create a reusable procedure that could operate independently 
        in any script. Good script management should include careful 
        evaluation of the task at hand to determine the most effective 
        solution. If the procedure is used all the time, you should 
        go ahead and create the object once and simply reference 
        its properties in the individual procedures. 
      Second, access intrinsic objects directly. As we’ve previously 
        discussed, many of the objects you’ll use in your scripts 
        are intrinsic, which means they’re automatically created 
        when you launch your script. Examples of these are the 
        ERR object and the WScript object (including the “Arguments” 
        collection). Instead of: 
      Dim objArgs, strArgs1, strArgs2
        Set objArgs=CreateObject(WScript.Arguments) 
        strArg1=objArgs.Item(0) 
        strArg2=objArgs.Item(1) 
      Try this: 
      Dim strArgs1, strArgs2 
        StrArgs1=WScript.Arguments(0) 
        StrArgs2=WScript.Arguments(1) 
      This solution helps reduce the number of objects created 
        but can cause extra coding if you use it a lot. (In the 
        example above it actually shortened the script, but that’s 
        misleading. Trust me, you’ll get tired of typing if you 
        access intrinsic objects in this manner all the time.) 
        Again, there’s a balance to be achieved. If your script 
        performs a great deal of logic against the component, 
        assigning it to a variable is the way to go. On the other 
        hand, if you simply need to retrieve one or two properties, 
        consider accessing the object directly. 
      “Get” This! 
      Thus far, we’ve been gaining access to built-in and third-party 
        components by either using “CreateObject” or by executing 
        a method of one object that creates another. There’s another 
        way of gaining access to certain components: “Get Object”. 
        GetObject returns a reference to an existing object (one 
        that has already been instantiated). This method of accessing 
        a component is perhaps best demonstrated by the Active 
        Directory Services Interface. In fact, GetObject is the 
        only way to gain access to the resources exposed by ADSI. 
      
      Over the next few months we’re going to take a good, 
        hard look at ADSI and how we can use it to perform a plethora 
        of useful administrative tasks. Since we’ll be starting 
        this new topic next month, I’m not assigning any homework 
        today. Take a break—you’ve earned it! 
      Now if you’ll excuse me, I have to find a shovel… I think 
        I hear my phone ringing.