2

vbScript - the basics

My plan is to post a series of hopefully useful and informative vbScript Functions and Subs. I started writing up my first code snippet and found that I was taking too many side trips to explain things about the vbScript syntax and language so I decided to postpone the first snippet until I had completed a vbScript intro.

There has been a lot of interest in scripting languages, most notably Perl and Python. While decidedly less versatile and powerful than Python, vbScript (which is way down on the list) has several good points to recommend it.

  1. It has a simple syntax
  2. It doesn't require a complex development environment
  3. It comes with every version of Windows
  4. Carefully written code can be easily ported to vb.Net
  5. It's great at tying software together/automating

The simple syntax still requires some effort to learn and some documentation. Even though Microsoft includes vbScript (cscript/wscript) with Windows, for some reason they have removed all traces of the associated help file, script56.chm. I've attached a zipped copy of that file with this post. Ignore the parts that relate to jscript.

Point number 2 notwithstanding, I find that having Visual Studio installed makes debugging much simpler as you can use the VS debugger to watch/single step through code just like you would a vb.Net or C# application.

For editing source code, while Notepad would do the job, there are much better (and free) editors available. While not free, I use TextPad and PrimalScript with a minor change to the colour scheme. I set my preferences to display comments with black text on a silver/grey background. This makes it obvious when code is commented out. It also makes the code (to me) more pleasing to look. I consider coding as much a form of artistic expression as a science. Source code is written for humans to read and only incidentally for computers to execute.

So in no particular order here's some things about vbScript.

Any really useful vbScript code will end up using one or more components. Some are built-in and some are external. Some of the more useful ones are not provided by Microsoft but are available for free such as AutoIT which is extremely useful for controlling other applications. Some of the more common internal objects are

Scripting.FileSystemObject (I almost always create this as fso for File System Object)
Wscript.Shell (usually wso for Wscript Shell Object)
Scripting.Dictionary

Other useful objects (file, drive, etc.) can be created using fso, wso, etc.

vbScript can be executed by two different hosts. cscript.exe is the console based host. Input and output is to the console (shell) but some windowed I/O (MsgBox, InputBox) is available. Executing under cscript gives you access to stdin, stdout and stderr (standard in, out, err) objects. wscript.exe is the windows based host. The default is wscript and I find it useful to change this otherwise each Wscript.Echo command will pop up a new output window. To set the default you must run a command shell as administrator and type

cscript //h:cscript //nologo //s

//nologo suppresses the output of version info. //s save the new values as default

vbScript files can have one of two extensions, vbs or wsf. The vbs form allows just vbScript code (simplest) whereas wsf allows a more complicated syntax that allows (among other things) including external files, defining objects, etc. External files can even be in jscript, allowing you to use features from both languages. I used wsf extensively in a production environment (pre-retirement), not so much now.

vbScript provides two ways of building and executing code on the fly, Execute and ExecuteGlobal. The first executes the code in the current scope. The second executes with global scope. What this means is that if you use Execute in a Function or Sub to create a variable, that variable will become undefined when the module returns. While dangerous, being able to build code on the fly can be useful. For example, in vbScript you can't do

n = 5
Dim a(n,n)

however, you can do

n = 5
Execute "Dim a(" & n & "," & n & ")"

although less clear, you could always document it as

Execute "Dim a(" & n & "," & n & ")"       'Dim a(n,n)

ExecuteGlobal gives us the ability to fudge an Include. I keep all of my include files in D:\Include and I have defined an environment variable, %INCLUDE% to contain that path. Thus, in my vbs files I can do

Include "%INCLUDE%\StrFuncs.vbs"

as long as I also have in the code file

Function Include ( ByVal file )
    Dim wso: Set wso = CreateObject("Wscript.Shell")
    Dim fso: Set fso = CreateObject("Scripting.FileSystemObject")
    ExecuteGlobal(fso.OpenTextFile(wso.ExpandEnvironmentStrings(file)).ReadAll)
End Function

In this case, executing the code just includes it in the global namespace.

vbScript supports a command line with both named and unnamed arguments. Named arguments are preceeded with a forward slash and followed by an optional value such as

reformat /file:myfile.txt
reformat /nolist

Unnamed arguments are gi v en with no forward slash such as

reformat myfile.txt

A command line can have both named and unnamed arguments. Named arguments are accessed through the collection Wscript.Arguments.Named and (obviously) unnamed through Wscript.Arguments.Unnamed. You can access all together through Wscript.Arguments. To see how they work, save and run the following code with various types of arguments

Wscript.Echo "all arguments"

For Each arg In Wscript.Arguments
    Wscript.Echo "arg=" & arg
Next

Wscript.Echo vbCrLf & "named only"

For Each arg in Wscript.Arguments.Named
    Wscript.Echo "name=" & arg, "value=" & Wscript.Arguments.Named(arg)
Next

Wscript.Echo vbCrLf & "unnamed only"

For Each arg in Wscript.Arguments.Unnamed
    Wscript.Echo "arg=" & arg
Next

Unnamed arguments can also be accessed by position (zero relative) as in

Wscript.Arguments.Unnamed(0)

vbScript does not support a Try-Catch block. It uses a more primitive method. Normally an error will result in an abort with an error message such as

D:\script\samples\test.vbs(1, 1) Microsoft VBScript runtime error: Division by zero

However, you can override this with

On Error Resume Next

Once you have done that, any errors will not halt execution, however you can detect the error with the err object as in

On Error Resuume Next

x = 5 / 0
if err.Number = 0 Then
    Wscript.Echo 'no error'
else
    Wscript.Echo err.Description
    err.Clear
end if

To restore normal processing of errors you can do

On Error Goto 0

which is hardly intuitive but there you go. If you do On Error Resume Next in a Function or Sub, On Error Goto 0 is done automatically when you return.

That's it for starters. I'll begin posting snippets shortly. General vbScript questions can be posted here. Questions about specific scripts can be posted in the specific snippet thread. I'll include a link to this intro in each new snippet.

1
Contributor
1
Reply
17
Views
3 Months
Discussion Span
Last Post by Reverend Jim
0

Tried to upload script56.zip but it was too big. The script56.chm and several other files can be downloaded here

Edited by Reverend Jim

Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.