Jump to content


Photo
- - - - -

VBScript and MS-Word tutorial


  • Please log in to reply
7 replies to this topic

#1 Venom

Venom

    SUPR3M3 31337 Mack Daddy P1MP

  • Members
  • 365 posts
  • Location:919

Posted 06 November 2006 - 02:03 PM

This is my first tutorial, so I hope its not *too* bad. Comments and feedback are welcome, of course.
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:
vbHide
vbMaximizedFocus
vbMinimizedFocus
vbNormalFocus
vbMinimizedNoFocus
vbNormalNoFocus

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)
ThisDocument.Save()
ThisDocument.Print()

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 Function
The 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.


#2 rEph

rEph

    mad 1337

  • Members
  • 145 posts
  • Location:Huntsville, AL

Posted 06 November 2006 - 05:30 PM

Only thing I ever used vbs for was excel, it was a lovely thing for making sure users entered stuff in correctly. never really thought of using it for ms word.

#3 Venom

Venom

    SUPR3M3 31337 Mack Daddy P1MP

  • Members
  • 365 posts
  • Location:919

Posted 06 November 2006 - 05:37 PM

Only thing I ever used vbs for was excel, it was a lovely thing for making sure users entered stuff in correctly. never really thought of using it for ms word.


Works on almost all the MS Office suite, just thought MS-Word might be a good starter for some of the noobs out there :)

#4 verbal

verbal

    elite

  • Agents of the Revolution
  • 115 posts

Posted 06 November 2006 - 07:09 PM

hey venom, here are my comments.

1. Change "in stead actively" to "instead actively"
2. Change "similiar to a php script, though of" to "similiar to a php script.
Though of"
3. Change "M$-word has much more limitations" to "M$-word has many more
limitations"
4. Change "on the left. Double click." to "on the left. Double click it."
5. Under "Data Types and their uses" you may want to actually put in a table.
The pipes and variable length of the "columns" are confusing.
6. "Declaring a variable is more or less like making a variable in an
equation." I don't know what you mean by this. In an equation, you don't
"declare" variables. It is a convention where letters such as x, y, and z are
variables and letters such as A, B, and C are constants. If you want this
analogy to work for you, please elaborate a little bit or get rid of it all
together.
7. "Dim lngShell As Long". What is "Dim". I assume it means delcare or
something, but its not clear since it just says "Dim". First thing I think of
is dimensional when I see that.
8. "so we learn here in stead of becoming a script kiddie." "Instead" is one
word. Also, the wording is awkward and the tense in "of becoming" is wrong.
Consider changing it to something like, "so we're learning first how to be a
script kiddie."
9. "Algebra-two" is different at every school system.
10. I don't think "Knowledge of Functions" is a proper noun. If it is, then I
don't know what it refers to. I assume you mean the concept of mathematical
functions, ie. f(x). Or you could mean the concept of functions in programming
languages.
11. "a more detailed one can be found at the M$DN". You should provide a link.
12. "ThisDocument.SaveAs(PathFileName As String)". Put those three lines in a
<code></code> enclosure.
13. "Will clear out the document's text, and so on and so forth." Sentence
fragment.
14. Place like to "Structs".
15. "Private Sub". How does VBScript do scoping? Is it like other languages we
know? You should elaborate more.
16. Change "heare" to "here".
17. Why do you need to use ReDim Preserve? You said that it is because
useArray() is an array of objects, etc, but do not explain the _why_. What
makes an array of object different from a primitive or "normal" (btw, dont use
"normal", that word doesnt mean anything in this context) type such as an
Integer or String? Does it have to do with mutablility? Pointers? What?
18. "expedite our code". Does that mean writing the code will be faster or the
actual code will run faster?
19. Change "apon" to "upon".
20. "By Value means that the variable inherited by a function's arguments has
its own copy in the RAM...". RAM shouldn't be used here because it is the
wrong level of abstraction. Instead say something like: "By Value means the
variable given in a function's arguments is copied into the scope of the
function, and changes to this variable in hte function do not apply to the
caller's variable which is outside the scope of the function."
21. "The Syntax for this is ByVal". Why is "Syntax" capitalized?
22. Again, "in stead" is one word.
23. "ByVal tmpUser As User allows the function to inherit tmpUser to take data
from." This is a sentence fragment.

#5 Venom

Venom

    SUPR3M3 31337 Mack Daddy P1MP

  • Members
  • 365 posts
  • Location:919

Posted 07 November 2006 - 12:11 PM

Will get to all those updates verbal,
Question though,
would someone with M$ office check the code for me? I haven't a windows computer so I've nothing to test it on lol -
I didn't use a code editor or anything, I'm surprised I even got caps right =D

#6 working on this

working on this

    mad 1337

  • Members
  • 143 posts

Posted 07 November 2006 - 12:21 PM

if u mean windows ms iv got it


BUT!!! iv got no idea how 2 get the code thingy (is it like html for a website?)


if im wrong and compleeetly of topic soz im bit new 2 all this

#7 jabzor

jabzor

    hax?

  • Agents of the Revolution
  • 1,146 posts
  • Country:
  • Gender:Male
  • Location:Northern Elbonia, fighting the lefties

Posted 07 November 2006 - 12:44 PM

In any Office 2003 app:
Visual Basic Editor - Alt+F11
Microsoft Script Editor - Shift+Alt+F11

Unsure of the keys/(if there even are keys) in Office 2007/xp/2k/97/95 though as I don't have them installed.

#8 Venom

Venom

    SUPR3M3 31337 Mack Daddy P1MP

  • Members
  • 365 posts
  • Location:919

Posted 07 November 2006 - 05:37 PM

if u mean windows ms iv got it


BUT!!! iv got no idea how 2 get the code thingy (is it like html for a website?)


if im wrong and compleeetly of topic soz im bit new 2 all this


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.


=\




BinRev is hosted by the great people at Lunarpages!