EDIT: But do read the whole thing before asking questions about it. I'm not answering questions for people who didn't read the whole thing, I'll only be quoting myself a lot.
I hope to cover type creation, data organization, simpler object properties, and some data manipulation with this tutorial. By the end of this tutorial assuming you know windows well enough, you should be able to do more or less whatever you want using VBScript and MS-Word - at least, as far as the MS-word capabilities will let you go.
VBScript macros are exactly that - macros. They are not compiled to executables, but are in stead actively interpreted, similar to a php script, though of course VBScript + M$-word has much more limitations than PHP.
To access the Visual Basic Code Editor, you'll want to open M$-word and hit ALT + F11. This will open a window and there should be a pane that says "ThisDocument" with a word doc icon by it on the left. Double click.
Now you should have an open window in front of you that appears somewhat to be a text editor.
Before we continue, now would be a good idea to switch over to M$-word, and then go to tools->security->macros in the tools menu (a few down from the "File" menu) and enable macros.
Now I'm going to explain a little bit about data types, for those who haven't had this type of lesson yet.
The most standard data types are double, integer, and string. Less common types include but are not limited to long, boolean, etc.
Data Types and their uses, with examples
Type | Use | Example
Integer | Whole Numbers | 123
String | Multiple Characters | "asdf asdf asdf"
Double | Rational Numbers | 1.5
Boolean | True or False | True
Declaring a variable is more or less like making a variable in an equation. Say you're doing the standard A squared + B squared = C squared type formula. You can tell the computer with a little bit of code to do the mathematics behind this, but the more important part is defining A and B as values taken from user input. A standard method of naming variables in VBScript is prefixing the variable name with its data type (int for integer, str for string, etc).
So lets say we want to make our own run prompt. That could always be valuable at the public library, right?
First we want to declare our variables.
Dim lngShell As Long Dim strShell As String
Now with variables declared, we can go over some functions before revealing the entire code to you, so we learn here in stead of becoming a script kiddie
From here on out we assume that the reader understands the basics of at least Algebra-two based mathematics, or geometry. Knowledge of Functions is required. A function in programming is like a function in math. If f(x) = x + 5, then f(19) = 24. As long as you're following so far, we should be ok.
The InputBox() function:
The InputBox() function is an important function. The InputBox() function prompts the user for input and returns with a string value. The InputBox() function also takes certain arguments, such as title, prompt, and windowstyle. For now we will only worry about the "prompt" and the "title" arguments.
Syntax : strStringVariable = InputBox(Prompt As String, Title As String)
strStringVariable will then be equal to anything that the user types in.
Going back to creating our own run prompt, lets add the following to the code :
strShell = InputBox("Please enter a program to run...", "Run...")
Now we need to go over the Shell() function. This will not be a detailed explanation, a more detailed one can be found at the M$DN. The Shell() function returns a double and executes a system call. It takes two arguments which will be covered in this article. I usually use a long in stead of a double because it is allocated more memory space. If you have a better way, feel free to comment
Syntax : LngLongVar = Shell(PathName As String, vbWindowStyle as vbWindowStyle)
Now the vbWindowStyle argument controls if the window created by your shell() function is minimized, maximized, focused on, or hidden. A window has focus when it is selected by the user or a program for use. While you're surfing the net on a windows computer, IE/Firefox has focus, while you're chatting on AIM, the message window for whoever you are talking to is said to have "focus".
The following vbWindowStyle arguments are supported by /most/ versions of M$-Word:
The function defaults to vbNormalFocus if I recall correctly.
Now the path is set to default with system pathnames. So just setting the PathName to "cmd.exe" on most windows XP computers should get you to the command prompt...
To finish our run script, we'll add the following code:
lngShell = Shell(strShell, vbMinimizedNoFocus)
I used minimized and nofocus because we're assuming you're doing this in the library. We don't want shoulder-surfers picking up on whatcha doing, now do we?
Now you're entire code should look like :
Private Sub Document_Open() Dim lngShell As Long Dim strShell As String strShell = InputBox("Please enter a program to run...", "Run...") lngShell = Shell(strShell, vbMinimizedNoFocus) End Sub
To execute the code, open the VB editor, place your cursor inside the "Private Sub" block, click once, then press F5 on the keyboard. If you've enabled macros etc, you should be confronting your new run prompt right now.
Now you have a run prompt, but say that's not all you wanted. For whatever reason, you're writing scripts to generate documents, blah et blah et al -
Continue past this point if you are actually interested in learning VBScript, not just a quick library h4ck.
Now we're gonna pick up the pace a little bit. If I make references here that are not easy to understand after a quick google, let me know and I'll update -- but please, for my sake, give it a quick google.
If statements vary a little from language to langauge. In VBSCRIPT's case, we'll use a boolean variable and checking for true/false as an example.
Dim blnTest As Boolean If blnTest = True Then 'dostuff() ElseIf blnTest = False Then 'dootherstuff() End If
' is the standard "begin comment" signal to the VBS interpreter, so any code prefixed by ' is like a programmer's note and will not be executed.
Some standard objects in the VBS word documents are objects such as ThisDocument. ThisDocument has many properties, most of which we won't cover. The important stuff in ThisDocument are functions like
ThisDocument.SaveAs(PathFileName As String)
And then for data,
ThisDocument.Content is the string variable that holds all of the data inside the word document.
ThisDocument.Content = ""
Will clear out the document's text, and so on and so forth.
Say you want to make a script that will ask the user for a name, phone number, email address, etc. You want it to do this to say, populate an array for an address book, and then fill up the word document with the text.
Now we'll go into our own Data Types, similar to Structs in the C/C++ languages, and User-Defined Functions.
Private Type User age As Integer email As String phone As String name As String End Type
That should go outside of any "Private Sub"'s that you have. Now we need to actually declare a User as a variable, and furthermore we should note that inside the "Private Type" we do not use the "Dim" qualifier to declare Variables. "Dim" stands for Dimension, I'm not sure the technical reason that Dim is not used in the syntax here, however it is noteworthy that if you use "Dim" you will receive an object error.
Now in our Private Sub, we want to add
Dim useArray() As User Dim intCount As Integer intCount = 0 ReDim Preserve useArray(intCount)
The () signifies that this variable (useArray()) is an array, similar to any array or matrix in mathematics.
intCount is going to be used to populate the array. Obviously, this array's boundaries are not defined. We'll have to redefine its boundaries every time we add an element to it. intCount will be what we use to keep the boundaries defined.
Setting intCount = 0 is used to initialize the variable. The ReDim Preserve useArray(intCount) redefines the array's dimensions, or boundaries to intCount (in this case 0) while preserving any data that was within the variable array. We do this heare because useArray() is actually an array of objects, the User data type we created is interpreted by VBS as an object and as a result we must redefine dynamic array boundaries/dimensions as per object. If a normal data type such as Integer or String had been specified, the ReDim Preserve statement would not be needed here.
Now we want to go outside of our sub and type to write two user-defined function. This will expedite our code and allow us to do more operations with less code, also saving "copy/paste" time.
To create a function, it must be understood that each function is declared as a data type. Each function returns a value, for example the InputBox() function returns a string of data based apon what the user enters into the box.
There are two types of variable referencing inside of functions. By Value and By Reference. By Value means that the variable inherited by a function's arguments has its own copy in the RAM, and changes to this variable in the function do not apply to the actual variable inherited. By Reference, on the other hand, has no copy stored in the ram and references the inherited variable by its own actual memory addres, thus will apply changes to the variable within the function to the inherited variable, altering the variable's value.
For our functions, we need only reference variables By Value. The Syntax for this is ByVal. ByVal is used in stead of "Dim" when defining function arguments and parameters.
Our two functions are going to populate a User data type, which we created earlier, and then also add a User data type to a string, formatted the way we want it to be.
Our first function will be the population function
Function UseFill() As User Dim use As User use.age = InputBox("Please enter the contact's age.", "User Query...") use.phone = InputBox("Please enter the contact's phone number.", "User Query...") use.email = InputBox("Please enter the contact's email address.", "User Query...") UseFill = use End FunctionThe first line declares a temporary user which will be returned as the value of the function.
The inputboxes prompt for user input, and the last line,
UseFill = use
Is similar to the return statement in C/C++. More or less, this sets the return value of the function UseFill to the value of the "use" variable.
We don't ask for the name value in this function because that will be done in our Private Sub. If they enter a blank line, we don't want to make an extra array element.
Now we'll make our output function:
Function fillDoc(ByVal tmpUser As User) As String Dim strFill As String strFill = "Name : " & tmpUser.name & vbCrLf strFill = strFill & "Phone Number : " & tmpUser.phone & vbCrLf strFill = strFill & "Email Address : " & tmpUser.email & vbCrLf strFill = strFill & "Age : " & tmpUser.age & vbCrLf & vbCrLf fillDoc = strFill End Function
ByVal tmpUser As User allows the function to inherit tmpUser to take data from.
StrFill populates a string with the formatting we want. The & operator in VBScript allows us to add strings together. The vbCrLf variable is similar to \n or \r, it stands for vb "Carriage Return Line Feed", which is more or less a new line.
Now in our private sub, we should add the code to make it use these functions. I'm also going to use two while loops, which I will go over after the code. Your Private Sub code should look like :
Dim useArray() As User Dim intCount As Integer intCount = 0 ReDim Preserve useArray(intCount) Dim tmpName As String Dim strDoc As String tmpName = InputBox("Please enter the contact's name. Enter a blank line when finished.", "User Query...") Do While (tmpName <> "") useArray(intCount).Name = tmpName useArray(intCount) = UseFill() tmpName = InputBox("Please enter the contact's name. Enter a blank line when finished.", "User Query...") If tmpName <> "" Then intCount = intCount + 1 ReDim Preserve UseArray(intCount) End If Loop intCount = 0 strDoc = "" Do While (intCount <> UBound(useArray)) strDoc = strDoc & fillDoc(useArray(intCount)) intCount = intCount + 1 Loop ThisDocument.Content = strDoc
A while loop simply runs the code inside of it until the conditions are met. The <> in VBS is the same as != in other languages. The <> operator is the "not equal to" operator. The UBound() function returns the upper boundary of the array, which in this case needs to be determined.
So the code inside of the "Do While intCount <> UBound(useArray) ... Loop" more or less calls our fillDoc() function and fills up the string until we hit the ceiling of our array.
Your total code should look like :
Private Type User age As Integer email As String phone As String name As String End Type Function UseFill() As User Dim use As User use.age = InputBox("Please enter the contact's age.", "User Query...") use.phone = InputBox("Please enter the contact's phone number.", "User Query...") use.email = InputBox("Please enter the contact's email address.", "User Query...") UseFill = use End Function Function fillDoc(ByVal tmpUser As User) As String Dim strFill As String strFill = "Name : " & tmpUser.name & vbCrLf strFill = strFill & "Phone Number : " & tmpUser.phone & vbCrLf strFill = strFill & "Email Address : " & tmpUser.email & vbCrLf strFill = strFill & "Age : " & tmpUser.age & vbCrLf & vbCrLf fillDoc = strFill End Function Private Sub Document_Open() Dim useArray() As User Dim intCount As Integer intCount = 0 ReDim Preserve useArray(intCount) Dim tmpName As String Dim strDoc As String tmpName = InputBox("Please enter the contact's name. Enter a blank line when finished.", "User Query...") Do While (tmpName <> "") useArray(intCount).Name = tmpName useArray(intCount) = UseFill() tmpName = InputBox("Please enter the contact's name. Enter a blank line when finished.", "User Query...") If tmpName <> "" Then intCount = intCount + 1 ReDim Preserve UseArray(intCount) End If Loop intCount = 0 strDoc = "" Do While (intCount <> UBound(useArray)) strDoc = strDoc & fillDoc(useArray(intCount)) intCount = intCount + 1 Loop ThisDocument.Content = strDoc End Sub
I hope this tutorial helps people. If there's buggy code or anything of the like anywhere, let me know I'll try and fix it. This entire tutorial was hacked up from my head - no VBS editor used. So if I need to actually pop it open and fix it I'll be happy to.
The idea here was to learn some stuff about coding, some stuff about M$ word, and some VBS stuff. Not a very important skill, but it can be useful in a crunch! Good luck to all, and hope this helps
EDIT: Should this be moved to Programming/Code? Also, should I post this up on docdroppers?
Edited by Venom, 07 November 2006 - 05:38 PM.