Rumor has it that the .NET Framework is inaccessible from VBScript. It’s true that support for VBScript was never implied or included, and it's also true that VBScript cannot instantiate native .NET Framework classes. But that doesn’t mean that the .NET Framework is off limits for scripters—at least, not all of it.
Contributed by Nilpo Rating: / 2 December 22, 2008
Have I gotten your attention yet? I thought I saw a few ears perk up out there.
Some of the .NET Interops do provide COM-scriptable interfaces, and probably more than you think! You're not going to find a list of these anywhere; nor will they be marked this way in the MSDN documentation. But with a little bit of trial and error you can discover them for yourself-well, at least the ones that I don't show you first.
I'm not going to list and document each of these interops. Instead, I'm going to take a topical approach and let you see them in action, providing explanations as I go. Keep in mind that this article is just the tip of the iceberg and is only meant to serve as an introduction to the concept of implementing .NET interops in VBScript. There is much more available to you than you will see presented here.
Finally, as you begin to explore these interops you will likely need to visit the MSDN documentation to examine the capabilities of each interop. Although you may find one that can be instantiated in VBScript, it's important to remember that all of its members may not be exposed through a scripting interface. You will likely need to perform some trial and error tests to get it working.
Admittedly, VBScript does not have very good support for working with arrays. It lacks many necessary features that are common to other languages. One example of this is the ability to sort the elements in an array. While Jscript provides adequate support for this, VBScript does not. Thankfully, .NET also provides support for this in a scriptable COM interop.
Set DataList = CreateObject("System.Collections.ArrayList")
DataList.Add "B"
DataList.Add "C"
DataList.Add "E"
DataList.Add "D"
DataList.Add "A"
The System.Collections.ArrayList class creates a specialized collection object. As with traditional collections, you can add data using the Add method. It also exposes several methods that are not available to traditional collection objects.
DataList.Sort()
For Each strItem in DataList
WScript.Echo strItem
Next
The Sort method will sort the data elements in ascending order.
DataList.Reverse()
For Each strItem in DataList
WScript.Echo strItem
Next
The Reverse method can be used to reverse the order of the elements. Using this method in conjunction with the Sort method results in a descending order.
DataList.Remove("D")
WScript.Echo "Count:", DataList.Count
DataList.RemoveAt(3)
WScript.Echo "Count:", DataList.Count
Elements can also be removed from the collection by value or index with the Remove and RemoveAt methods respectively. You can also see how the Count property returns the number of elements in the collection.
DataList.Insert 3, "C"
WScript.Echo "Count:", DataList.Count
You can insert data at a specific index by using the Insert method. Elements after the specified index will be increased by one. The capacity of the collection will be automatically increased to house the new data without losing any existing elements.
arrData = DataList.ToArray
For i = 0 To UBound(arrData)
WScript.Echo arrData(i)
Next
You can return a standard array of the elements in the collection by using the ToArray method.
DataList.Clear()
WScript.Echo "Count:", DataList.Count
Finally, there is also a clear method for dumping all remaining elements at once.
.NET interops can also be used to do some advanced string manipulation. One example of this is the ability to produce formatted strings. Formatted strings are dynamically generated strings. Take this classic VBScript example.
arrOne = Array(1, "loneliest")
arrTwo = Array(2, "happiest")
WScript.Echo arrOne(0) & " is a " & arrOne(1) & " number"
WScript.Echo arrTwo(0) & " is a " & arrTwo(1) & " number"
This code uses some array data to dynamically construct string output. This is the same technique you've seen used over and over again to produce an output like the following:
1 is a loneliest number 2 is a happiest number
A formatted string would be one whole string that contained markers where the array data could be inserted without having the mess of concatenating several strings into one.
Set sb = CreateObject("System.Text.StringBuilder")
sb.AppendFormat_5 Nothing, "{0} is a {1} number" & vbCrLf, Array(1, "loneliest")
sb.AppendFormat_5 Nothing, "{0} is a {1} number" & vbCrLf, Array(2, "happiest")
WScript.Echo sb.ToString()
Here we're using a single string of the form "{0} is a {1} number." Each number in brackets indicates a marker where a substring is to be inserted. The substrings are found in the array provided.
Once all substitutions have been made, they are added to the StringBuilder object using the AppendFormat_5 method. As it turns out, the AppendFormat method of the StringBuilder object is an overloaded method. This means that there are several different methods with the same name that accept different types of parameters. Since VBScript does not support overloaded methods, each of these overloads are exposed by the COM object as separate, numbered methods. In this case, we're using the fifth overloaded AppendFormat method.
The StringBuilder object then provides a ToString method that returns a single string that has been constructed.
There's plenty more you can do with the StringBuilder object as well. Let's take a look at some other string manipulations.
sb.Replace "loneliest", "saddest"
sb.Replace "happiest", "luckiest"
WScript.Echo sb.ToString()
Here I'm using the Replace method to replace one substring with another. This is quite similar to VBScript's own Replace function.
sb.Remove 7, 8
sb.Remove 21, 9
WScript.Echo sb.ToString()
You can also use the StringBuilder object's Remove method to remove sequences of characters. The first parameter is a starting index and the second is the number of characters to remove. I've used it here to remove the words "saddest" and "luckiest", respectively.
sb.Insert_2 7, "saddest "
sb.Insert_2 30, "luckiest "
WScript.Echo sb.ToString()
Not too worry, though. We can just as easily add them back in with the Insert method. Here again we have an overloaded method. The second variation of the Insert method allows us to provide an integer-starting index and a string to insert.
WScript.Echo sb.Length
Having trouble keeping track of how long your string is? The StringBuilder object also exposes a few properties that may come in handy. One of these is the Length property, which returns an integer representing the length of the string.
Okay, one more quick .NET bite before I go. One very lacking feature in VBScript is its ability to produce random numbers. It's not very efficient, and quite honestly, not very random. Its seeded values make it difficult to produce anything close to a truly random number.
Set objRandom = CreateObject("System.Random")
WScript.Echo objRandom.Next_2(1,100)
Enter .NET to the rescue. This example shows you how to produce random integers between 1 and 100. The second overloaded Next method allows you to specify a lower and upper limit, respectively.
Well, that's it for me, folks. I'm out of space in this article. You may or may not have a use for any of the code in this article, but at least now you know that .NET is not completely unavailable to you for scripting. Until next time, keep coding!