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.
- It has a simple syntax
- It doesn't require a complex development environment
- It comes with every version of Windows
- Carefully written code can be easily ported to vb.Net
- 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,
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,
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
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
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
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.