Resting Anchor

The Anchorage

Personal website of Gregory K. Maxey, Commander USN (Retired)

"Hangman for Word" (A Class Study)
(A Microsoft Word Help & Tip page by Gregory K. Maxey)

DISCLAIMER/TERMS OF USE

The information, illustrations and code contained in my "Microsoft Word Tips" are provided free and without risk or obligation.

Click to acces PayPal Verification Service Click to acces PayPal Verification Service

However, the work is mine. If you use it for commercial purposes or benefit from my efforts through income earned or time saved then a donation, however small, will help to ensure the continued availability of this resource.

If you would like to donate, please use the appropriate donate button to access PayPal. Thank you!

Click to donate British Pound Sterling                   Click to donate US dollars                   Click to donate EU euros

This Microsoft Word Tips & Microsoft Word Help page introduces "Hangman for Word," a game developed in Microsoft Word with Visual Basic for Applications (VBA).

For the more serious minded, I hope to offer a "class study" or introduction and demonstration of the versatility and benefits of using custom class objects in your VBA projects.  In any case, perhaps "Hangman for Word" will provide hours of fun for the players.

Hangman for Word

To play Hangman for Word, download the template file here.  After downloading the file, you can initiate play in one of three ways:

Site Note Icon For more on template add-ins and how to load them, see: Organizing Your Macros/Template Add-ins at: Installing Macros

     Documents containing the code and class modules for the demonstrations that follow are also available in the download link.

Using either method above adds a ribbon control to the ribbon Add-Ins tab.

hangman_1

After clicking the ribbon control, the game console is displayed:

hangman_2

There are two modes of play:

  1. Single player game using a randomly selected game word (default).
  2. Two player game using an opponent defined game word.

The game console is setup to automatically begin a single player game.  A random game word is already defined.  All you have to do to begin play is guess and select a letter.

For the two player game, the challenger can define and set a game word before beginning play.  After a new game word is defined and play begins the game console is reconfigured.

hangman_3

From this point on, game play is self explanatory.

Class Study

What is a Class

If you are a beginner (dabbler) or intermediate (tinkerer) with VBA then you are probably familiar with the project standard code modules and perhaps even Userform.  When you insert a new userform or standard module in your project you might wonder, "What is a Class?"

hangman_4

VBA is a pseudo "Object Oriented Programming" (OOP) language; meaning that it works with "objects" and the "properties" and "methods" of those objects.  I say pseudo OOP, because unlike a true OOP language, VBA doesn't have "inheritance" or "polymorphism."  You can Google OOP, inheritance or polymorphism to learn more about each of them.

Site Note Icon Note: Anything you do learn about inheritance or polymorphism will be more than I know!

A class serves as a template for defining objects.  It is like a blueprint of the object.

The truth is that if you have ever used VBA then you have been using classes from the very beginning.  The classes you have used are all built-in to the application object model. For example, in Word, a document is an object of the document class because:

VBA Script:
Sub SimpleStuff()
Dim oDoc As Word.Document
  'The ActiveDocument is and instance of the document class because:
  '1. It is an object.
  MsgBox IsObject(ActiveDocument)
  '2. It has properties such as "Name."
  MsgBox ActiveDocument.Name
  '3. It has methods such a "Printout"
  ActiveDocument.PrintOut
  'You can create new instances of the document class and each instance _
  'follows the rules established in the class:
  Set oDoc = Documents.Add
  MsgBox oDoc.Name
End Sub

So a "Class Module" or better a "custom class" is just an object that you can define yourself. You define its properties and methods, and when done properly you can create new instances of your class which will follow the rules that you define.

A Real World class

Think about you and me. As a person your and I are a class in a sense. Yes, and some persons are are more classy than others.  Regardless we are an object.

The human class developer being far more omnipotent than me has created our classy selves with nearly an infinite number or properties and methods. Furthermore, when two of us person objects with the right properties get together new objects of the class are often instantiated (created).

A class object like a person is created, it has properties and methods, and still like people it eventually reaches the end of its useful life and dies (terminated or disposed of in VBA speak). 

A Simple Custom Person Class

I think you get it now, so it is time to demonstrate a custom class in simplest form.  In this demonstration you will see how an object of the class is instantiated, assigned properties and a method, and eventually terminated.

Our person object will have two properties "Name" and "Age" and a single method "Aging."

The class properties in this demonstration are "simple" properties meaning they are declared as public variables in the class.

Site Note Icon Note: Purist will frown on using public variable declarations in a class and the debate is one that I am not really qualified to enter.  They have their advantages and disadvantages.  I use them sparingly in my projects and I feel that you should be aware of them.  I will cover private variable declarations and Get/Let property pairs in the next demonstration.

To create the demonstration you will need to:

Standard Module:
Sub DemoClass()
'Place your cursor here and step through this code using the F8 key.
Dim oPerson As clsPerson
  'Create the object.
  Set oPerson = New clsPerson
  'Define the public property "Name"
  oPerson.Name = "Billy"
  Do
    'Time marches on.
    oPerson.Ages
    If oPerson.Age > 70 Then Exit Do
  Loop
lbl_Exit:
  'Note what happens in the clsPerson terminate event when _
  the procedure exits and the oPerson object falls out of scope.
  Exit Sub
End Sub
clsPerson module code:
Option Explicit
'Publicly declared variables.
Public Name As String
Public Age As Long

Private Sub Class_Initialize()
  'The object is born and its Age property is set to 0.
  Age = 0
End Sub

Sub Ages()
  'The aging method.
  Age = Age + 25
End Sub

Private Sub Class_Terminate()
  MsgBox "Like all of us, our person grows older eventually dies."
End Sub

There you have it.  You've created and demonstrated your first simple class and hopefully you are grasping the concept.

Complicating the Class

Now let's complicate things.  Classes like people can be as simple or complex as the developer makes them.

First let's look at the advantages and disadvantages of the simple publicly declared class variables "Name" and "Age" in our simple custom person class.

The advantage of course is simplicity.  By declaring the variable public, you automatically expose it externally to other modules (i.e., the standard module) as a read\write property of the class.

No problem there for "Name" property as a persons name can be nothing or anything at all.  However, consider if you added this line of code in your standard module:

As you surely know a person's age is based on their date of birth and it certainly cannot be a negative number!

Simple class properties (i.e., publicly declared) are by default read/write and unless they are self-validating (e.g., a Boolean variable), cannot be validated or further processed in the class.  This can be a show stopper and a "BIG" disadvantage!

In the next demonstration you will see how to use private class variables and property Get, Let or Set statements in your class module code.  This allows you to define "Read Only or Write Only" class properties as well a validate  the property and keep your cod encapsulated.

To create the demonstration you will need to:

Standard module:
Sub DemoClass()
'Place your cursor here and step through the code using the F8 key.
'A custom class is a an object. To use a grammar analogy, _
 a class is like a noun (person, place, or thing).
Dim oPerson As clsPerson
Dim lngIndex As Long
  'Objects must be created.  Like in the real world, people must be born, _
  cities must be built, things must be manufactured.
  Set oPerson = New clsPerson
  'Objects have decriptive properties. _
   The person has a birth date, gender and name.
  oPerson.Gender = "Male" 'Determined as inception.
  oPerson.BirthDate = "9/1/2003"
  If oPerson.Gender = "Male" Then
    oPerson.Name = "Dick"
  Else
    oPerson.Name = "Jane"
  End If
  
  'Objects can have other objects.  A tree has leaves, the person object has hair.
  'These objects have properties. The person's hair has color and length.
  If oPerson.Gender = "Male" Then
    oPerson.Hair.Color = "Red"
    oPerson.Hair.Length = 2
  Else
    oPerson.Hair.Color = "Blonde"
    oPerson.Hair.Length = 10
  End If
  'What is our person like like?
  MsgBox "The " & oPerson.Development & "'s name is " & oPerson.Name & "." & vbCr _
        & oPerson.Name & " is " & oPerson.Age & " years old with " _
        & oPerson.Hair.Color & " hair." & vbCr _
        & oPerson.Name & "'s hair is " & oPerson.Hair.Length & " inches long." & vbCr _
        & oPerson.Name & " is spending the summer at the beach."
  'During the summer:
  'In addition to properties, objects can have methods.  Using the grammar analogy _
   again, methods are like verbs.
  For lngIndex = 1 To 3
    'The persons hair hair grows.
    oPerson.Hair.Grow
  Next lngIndex
  If oPerson.Gender = "Male" Then
      MsgBox oPerson.Name & " is back home now." & vbCr _
      & oPerson.Name & "'s hair is now " & oPerson.Hair.Length & " inches long."
  Else
    oPerson.Hair.Cut
    MsgBox oPerson.Name & " is back home now." & vbCr _
         & "She went to the hair dresser's before coming home." & vbCr _
         & oPerson.Name & "'s hair is now " & oPerson.Hair.Length & " inches long."
  End If
  
  'Like all things, classes must eventually come to an end or be terminated. _
  People die, cities crumble, things are destroyed.
  Do
    'The person ages.
    oPerson.Ages
    Debug.Print oPerson.Age
    'As the person ages his or her development changes.
    If oPerson.Age = 40 Then MsgBox "Lordy, Lordy our " & _
       oPerson.Development & " is now forty."
    If oPerson.Age > 70 Then Exit Do
  Loop
lbl_Exit:
  'Note what happens in the clsPerson terminate event when the procedure exits _
   and the oPerson object falls out of scope.
  Exit Sub
End Sub
clsPerson module code:
Option Explicit
'Class objects can have Public or Private variables.
'Public variables are by default exposed as read\write properties of _
 the class that cannot be validated.
Public Name As String
'Private class variables used in Property Get/Let/Set statements _
 to define class properties.

Private m_strGender As String
Private m_dtdBirthDate As Date
Private m_lngAge As Long
Private m_oHair As clsHair
'Private utility variable.
Private m_lngPassageOfTime As Long

Private Sub Class_Initialize()
  'From the dust our person object is formed.
  'Objects can have other objects as properties.  Trees have leaves, our person has hair.
  Set Hair = New clsHair
End Sub

'Gender is a Read\Write property of class. Requires paired Get\Let property statements.
Property Get Gender() As String
  Gender = m_strGender
End Property

Property Let Gender(strGene As String)
  m_strGender = strGene
End Property

'BirthDate, just becuase I wanted it this way, is a Write only property of the class.
Property Let BirthDate(oDate As Date)
  m_dtdBirthDate = oDate
End Property

'Age is a Read only property of the class. _
 The value is determined by the BirthDate and passage of time.
Property Get Age() As Long
 Age = CLng(DateDiff("yyyy", m_dtdBirthDate, Now)) + m_lngPassageOfTime
End Property

'Hair is a Read\Write "object" property of the class. _
 Requires paired Get\Set property statements.
Property Get Hair() As clsHair
 Set Hair = m_oHair
End Property

Property Set Hair(Object As clsHair)
  Set m_oHair = Object
End Property

'Development is a Read only property of the class.
Property Get Development() As String
  If m_lngAge < 19 Then
    If m_strGender = "Male" Then
      Development = "boy"
    Else
      Development = "girl"
    End If
  Else
    If m_strGender = "Male" Then
      Development = "man"
    Else
      Development = "woman"
    End If
  End If
End Property

Sub Ages()
  'A method of the class.
  m_lngPassageOfTime = m_lngPassageOfTime + 15
  m_lngAge = m_lngAge + m_lngPassageOfTime
End Sub

Private Sub Class_Terminate()
  MsgBox "Like all of us, our person grows older becomes a " & Development & ", " _
       & "eventually dies and returns to dust."
End Sub
clsHair module code:
Option Explicit
Private strColor As String
Private lngLength As Double

Property Get Color() As String
 Color = LCase(strColor)
lbl_Exit:
  Exit Property
End Property

Property Let Color(strInput As String)
  strColor = strInput
lbl_Exit:
  Exit Property
End Property

Property Get Length() As Double
 Length = lngLength
lbl_Exit:
  Exit Property
End Property

Property Let Length(lngInput As Double)
  lngLength = lngInput
lbl_Exit:
  Exit Property
End Property

Sub Grow()
  'A method of the class.
  lngLength = lngLength + 0.4
End Sub

Sub Cut()
  'A method of the class.
  lngLength = lngLength - 3
End Sub

Private Sub Class_Initialize()
  'The object is born.
  Beep
End Sub

Conclusion

If you've followed the demonstrations and made it this far then you should have a better understanding of what classes are and how to use them.

Don't worry if you have to step through the demonstrations more than once.  Classes are not easy to understand. For a long, long time I avoided them like the plague.  The Get/Let property pairs have kicked my butt more than once.  However, they do get easier with use and learning about them can offer the following advantages:

Now you are ready to look at the code in "Hangman for Word" many of the concepts and methods you've seen in the demonstrations were employed to create it.

To view a a considerably more advanced class tailored specifically to Microsoft Word, see the clsSentences in Deduced Sentences co-developed with Jason Simpson (AKA Frosty).

That's it! I hope you enjoy the game and that you've have found this tips page useful and informative.

Share

DISCLAIMER/TERMS OF USE

The information, illustrations and code contained in my "Microsoft Word Tips" are provided free and without risk or obligation.

Click to acces PayPal Verification Service Click to acces PayPal Verification Service

However, the work is mine. If you use it for commercial purposes or benefit from my efforts through income earned or time saved then a donation, however small, will help to ensure the continued availability of this resource.

If you would like to donate, please use the appropriate donate button to access PayPal. Thank you!

Click to donate British Pound Sterling                   Click to donate US dollars                   Click to donate EU euros

Search my site or the web using Google Search Engine

Google Search Logo