Previous Section Table of Contents Next Section

Writing Functions and Subroutines

Generally, any kind of subtask you've identified is a great candidate for a function or subroutine, because subtasks get used more than once. You'll need to carefully examine your subtasks and decide which ones should be written as functions or subroutines. I have a general rule that I use: If a subtask involves more than one line of VBScript to accomplish, I write it as a function or subroutine. If I can do it in one line of VBScript code, I don't bother with a separate function or subroutine.

If you need a quick refresher of functions and subroutines, flip back to "What Are Functions?" in Chapter 5.

Identifying Candidate Modules

In this log rotation tool, I've already identified two potential modules (functions or subroutines): The date calculation and the log filename bit. A quick read through the VBScript documentation leads me to the DateAdd function, which can be used to calculate past or future dates. That seems to cover the date calculation subtask, so I don't think I'll need to write a function for that. I do see several Format commands that will help format a log filename, but none of them seem to do everything that I need in one line of code (at least, not one reasonably short line of code); I'll write the filename formatter as its own module.

Writing the Filename Formatting Function

Before writing a function, I need to consider a couple of facts. One fact is that the function is designed to encapsulate some subtask. Therefore, the function is going to need some kind of input to work on, and it's going to give me back some result that my script needs. Defining that input and output is critical. I want the function to be generic enough to be reusable, but specific enough to be useful.

Defining Function Input

In the case of the filename formatter, I know that the filename is always going to start with "ex," so I don't need that information in the input. The filename will always end in .log, so I don't need that in the input, either. What changes from filename to filename is the date information, so that seems like a logical piece of information for the function's input.

Defining Function Output

I want this function to take a date-its input-and create a fully formatted log filename. The output is obvious: a fully formatted log filename.

Writing the Function

Writing the actual function code requires a bit more task definition. You need to really break the task of formatting a filename down into small pieces. This can be a tough process, because the human brain does so many things for you without conscious thought. Think about what a three-year old would have to do to accomplish this task: Remember, all they have to work with at the beginning is a date.

You might come up with a task list like this.

  1. Start with a blank piece of paper.

  2. Write "ex" on the piece of paper.

  3. On a separate piece of paper, write down the date you were given.

  4. Erase everything but the year.

  5. From the year, erase everything but the last two digits.

  6. Write those last two digits after the "ex" on the first piece of paper.

  7. On a new piece of paper, write down the date again.

  8. Erase everything but the month.

  9. If the month is only one digit long, add a zero to the front of it.

  10. Copy the two-digit month to the first sheet of paper, after the two-digit year.

  11. On a new piece of paper, write down the date one more time.

  12. Erase everything but the day.

  13. If the day is only one digit long, add a zero to the front of it.

  14. Copy the two-digit day to the first sheet of paper, after the two-digit month.

  15. On the first sheet of paper, add ".log" to what's already there.

  16. Return the contents of the first sheet of paper.

Now, that's a lot of detail! All you need to do is translate that into VBScript. First, figure out which VBScript functions seem to line up with each step in the task, and eliminate any redundant tasks.

  1. Declare a variable.

  2. Place "ex" into the variable.

  3. Declare a new variable to hold the year portion of the date.

  4. Use the DatePart command to extract the year.

  5. Use the Right command to take the last two digits of the year.

  6. Append the two-digit year to the variable.

  7. Declare a new variable to hold the month portion of the date.

  8. Use the DatePart command to extract the month.

  9. Use the Len command to figure out if the month is one digit; if it is, add a zero to the front.

  10. Append the month to the variable.

  11. Declare a new variable to hold the day portion of the date.

  12. Use the DatePart command to extract the day.

  13. Use the Len command to figure out if the day is one digit; if it is, add a zero to the front.

  14. Append the day to the variable.

  15. Append ".log" to the variable.

  16. Return the variable.

Now you're ready to put the translated task list into an actual script.

graphics/arrow.gif The FormatLogFileName Function

Listing 13.1 shows the function in VBScript.

Listing 13.1. FormatLogFileName Function. Accepts a date and returns an appropriate log filename.

Function FormatLogFileName(dDate)



 Dim sFileName

 sFileName = "ex"



 Dim sYear

 sYear = DatePart("yyyy",dDate)

 sYear = Right(sYear,2)

 sFileName = sFileName & sYear



 Dim sMonth

 sMonth = DatePart("m",dDate)

 If Len(sMonth) = 1 Then

  sMonth = "0" & sMonth

 End If

 sFileName = sFileName & sMonth

 

 Dim sDay

 sDay = DatePart("d",dDate)

 If Len(sDay) = 1 Then

  sDay = "0" & sDay

 End If

 sFileName = sFileName & sDay



 sFileName = ".log" & sFileName



 FormatLogFileName = sFileName



End Function

Now, that's the complete script for the function, and it's ready to be plugged into the main script.

graphics/arrow.gif The FormatLogFileName Function-Explained

This function simply extracts various parts of a specific date, appends them together, and returns the results. I start with a function declaration, which gives the function its name and defines its input. This function will receive a date, which will be stored in a variable named dDate.


Function FormatLogFileName(dDate)

End Function

Next, I declare a variable to store the filename, and put "ex" in that variable.


Dim sFileName

sFileName = "ex"

Then, I declare a new variable for the year. The DatePart function extracts the four-digit year from dDate, which was passed as input to the function. Then, the Right function grabs just the last two digits of that four-digit year. Finally, I tack those two digits onto the filename using the ampersand (&) operator.


 Dim sYear

sYear = DatePart("yyyy",dDate)

sYear = Right(sYear,2)

sFileName = sFileName & sYear

I use a similar set of steps for the month. Obviously, the DatePart command gets a slightly different parameter, so that it pulls the month out. This time, I'm not guaranteed of a two-character result.


Dim sMonth

sMonth = DatePart("m",dDate)

I compensate by using the Len function to see if sMonth is only one character long. If it is, I use the ampersand operator again to prepend a zero to the month, and then add the result to the filename I'm building.


If Len(sMonth) = 1 Then

 sMonth = "0" & sMonth

End If

sFileName = sFileName & sMonth

I perform the exact same set of steps again for the day portion of the date. Notice the difference in the DatePart command to pull the day, rather than the month or year. You can check out DatePart's other possibilities in the VBScript documentation.


Dim sDay

sDay = DatePart("d",dDate)

If Len(sDay) = 1 Then

 sDay = "0" & sDay

End If

sFileName = sFileName & sDay

Finally, I add the last part of the filename, ".log", to the variable I'm building. As the last step, I set the name of the function itself equal to the variable that contains the filename. This tells VBScript to pass back the completed filename as the result of the function.


sFileName = ".log" & sFileName



FormatLogFileName = sFileName

That's all there is to it. Now I have a completed function that rolls up an otherwise reasonably complicated task into a single command. Effectively, I have my own custom FormatLogFileName command, which I can use in the main part of my script.

Variable Names

This isn't the first time you've seen me name variables with a prefix letter like s or d. There's a good reason for this.

First, keep in mind that VBScript doesn't really care what type of data I put into a variable. Data types are all pretty much the same to VBScript. However, VBScript will get upset if I try to perform certain operations with certain data types. For example, if I store "Hello" into variable Var1, and store "Mom" in variable Var2, and then ask VBScript to calculate Var1 * Var2, I'll get an error because VBScript can't multiply two strings.

One purpose of my variable names, then, is to remind me what I've put into them. I use d when the variable contains data I intend to treat as a date, s for strings, i for integers, and so forth.

Another purpose is to avoid overlapping with VBScript reserved words. VBScript doesn't allow variable names to duplicate any of VBScript's built-in names or functions. For example, the VBScript Date() function returns the current system date. Because that's a built-in function, I'm not allowed to name a variable Date, because VBScript wouldn't be able to tell the difference between the built-in function and my variable. By using a name prefix like d, however, I can create a meaningful variable name like dDate without conflicting with VBScript's reserved words.


    Previous Section Table of Contents Next Section