Table Data and User Forms, or...

S

Steve

What I am wanting to accomplish is this:

I have a table that contains a list of words.

I would like to set this up so that if a user clicked on a cell in the table
a pop-up userform (or something) would appear with the definition for the
word that the cell contains.

Conceptually, it sounds simple enough, but I do not know how to accomplish it.

Does anyone out there have a clue about how to accomplish this task?

I thank you in advance.
 
J

Jay Freedman

Steve said:
What I am wanting to accomplish is this:

I have a table that contains a list of words.

I would like to set this up so that if a user clicked on a cell in
the table a pop-up userform (or something) would appear with the
definition for the word that the cell contains.

Conceptually, it sounds simple enough, but I do not know how to
accomplish it.

Does anyone out there have a clue about how to accomplish this task?

I thank you in advance.

As simple as it sounds, the mechanism is quite complex. Since (I assume)
you're dealing with a plain table rather than a table full of protected form
cells, there is only one way to get a macro to run when clicking in a cell.
That's to create an "event handler" that runs code every time the selection
(the cursor/insertion point) is moved by a click, an arrow key, or a tab.

The principles and construction of an event handler are described by MVP
Bill Coan at
http://msdn.microsoft.com/en-us/library/aa140279(office.10).aspx and his
similar article at http://word.mvps.org/FAQs/MacrosVBA/AppClassEvents.htm.
The code below is based on those articles.

The specific event that's needed here is WindowSelectionChange.

Following Bill's instructions, this code goes into the class module named
clsEventHandler:

'-------------------------------------------------------------
Option Explicit

'Declare that only an instance of Word can be assigned to this variable
'and also that the assigned instance should be notified to
'check inside the event handler for application event procedures.
Public WithEvents EventSource As Word.Application

Private Sub EventSource_WindowSelectionChange(ByVal Sel As Selection)
' Pop up definition of word in current table cell

' Exit as soon as possible if conditions aren't right
' ...check that the selection is in the right document:
If InStr(LCase(ActiveDocument.Name), "showdefs") = 0 Then Exit Sub

' ...check that the selection is in a table:
If Not Sel.Information(wdWithInTable) Then Exit Sub

' ...check that the selection is in the first column:
If Sel.Information(wdStartOfRangeColumnNumber) <> 1 Then Exit Sub

' if we get here, the conditions are all satisfied, so
' call the procedure in the regular code module modHandleEvents
DisplayDefinition Sel
End Sub

'-------------------------------------------------------------

IMPORTANT: You must change the quoted word "showdefs" in the code above to
match the file name of the document in which you want the definitions to pop
up. This prevents the event handler from trying to show definitions in any
other document.

You may want to change this check to one that looks at the name of the
ActiveDocument.AttachedTemplate or some other way to make sure the code
doesn't run in the wrong circumstances. You may also want to remove the
check for the first column, if that wasn't your intention.

Also following Bill's instructions, this code goes in the regular code
module named modHandleEvents:

'-------------------------------------------------------------
Option Explicit

' declare type of object to be stored in the objEventHandler variable
Dim objEventHandler As clsEventHandler

Sub CreateEventHandler()
'create a new event handler object and assign it to objEventHandler
Set objEventHandler = New clsEventHandler
'Notify the current instance of Word to check for
'application event procedures
'inside the event handler object
Set objEventHandler.EventSource = Word.Application
End Sub

Sub DestroyEventHandler()
'release the memory being used by the event handler object
Set objEventHandler = Nothing
End Sub

Sub AutoExec()
'whenever this template is loaded globally,
'automatically create an event handler
CreateEventHandler
End Sub

Sub AutoExit()
'whenever this template is unloaded,
'automatically destroy the event handler
DestroyEventHandler
End Sub
'-------------------------------------------------------------

Finally, the next procedure is added to the same module modHandleEvents. You
will have to change some things in here to match your requirements, as
described below the code.

'-------------------------------------------------------------
Sub DisplayDefinition(Sel As Selection)
Dim CellRg As Range
Dim WordToDefine As String
Dim Definition As String
Dim idx As Long
Dim DefStore(1, 2) As String

' fill the DefStore array
DefStore(0, 0) = "1"
DefStore(0, 1) = "2"
DefStore(0, 2) = "3"
DefStore(1, 0) = "one"
DefStore(1, 1) = "two"
DefStore(1, 2) = "three"

' the event handler assures that the selection is in a table cell
Set CellRg = Sel.Cells(1).Range
CellRg.MoveEnd wdCharacter, -1
WordToDefine = CellRg.Text

' find the word in the array
Definition = ""

For idx = 0 To UBound(DefStore, 2)
If DefStore(0, idx) = WordToDefine Then
Definition = DefStore(1, idx)
Exit For
End If
Next

If Len(Definition) Then
MsgBox Definition, , "Definition"
End If
End Sub
'-------------------------------------------------------------

To make the needed changes, first make a list (on paper!) of the words and
their definitions. Count the number of words, subtract 1 from that number,
and put the result in the code in place of the number 2 in the line

Dim DefStore(1, 2) As String


Next, put the words into the lines that start with "DefStore(0," and add as
many of those as needed, increasing the second number as you go. The last
one should have a number that matches what you put into the Dim statement
above.

Put the definitions of the words into the lines that start with
"DefStore(1," and add as many of those as needed; again you should come to
the last one with the same number as before.

Check your work; for each value of N, the line for DefStore(1, N) should
contain the definition of the word in the DefStore(0, N) line.

Finally, follow Bill's instructions in the section "Test Your Event
Handler", except that instead of saving and printing you should test moving
the cursor into various table cells.

If you get here without problems, congratulations! Otherwise, post a reply.

--
Regards,
Jay Freedman
Microsoft Word MVP
Email cannot be acknowledged; please post all follow-ups to the newsgroup so
all may benefit.
 
F

fumei via OfficeKB.com

Oh, and Steve, Jay's comment:

"If you get here without problems, congratulations! "

is not, I believe, meant in any sarcastic way (I do not think I have ever
seen Jay be sarcastic). It is a reality comment. As you can see, the
reality to accomplish what you are asking for is do-able, but for sure it is
not trivial. Congratulations would indeed be in order if you got it to work
as you imagine without problems.

It is a worthwhile project to attempt. You would definitely increase your
understanding immensely.
Jay.....loved your response. It made me laugh and feel awed at the same time.

Not only did you give a full and detailed response (with references), but you
(hopefully) demonstrated to the OP how sometimes what may seem "simple" can
be quite complex. Of course, in some situations, the reverse is true. What
may seem complex is actually quite simple...although that does not happen
often enough. LOL.

I particularly liked your comment:

"To make the needed changes, first make a list (on paper!) of the words and
their definitions."

Indeed. Things work much better when we do a bit of writing things out on
paper beforehand.

Bravo. Great response.
[quoted text clipped - 157 lines]
If you get here without problems, congratulations! Otherwise, post a reply.
 
S

Steve

Jay,

Thank you for replying to my post.

I copied the code and followed your instructions.

When I click on a table cell it appears to do nothing.

If I step through the code, starting with AutoExec it executes this
procedure. The only line of code is: CreateEventHandler

It steps through this procedure, exits, returns to the AutoExec procedure,
and exits.

It never gets beyond this.

I checked the Macro Security settings to make sure that macros were enabled,
and they were.

Any ideas?

Thanks again.

Steve McCain
 
S

Steve

Believe me when I say that I did not interpret Jay's comment as sarcasm.
Programming Word is not my strongest point, in fact, this is my first attempt
at it. I frequently program Excel. With that I am pretty comfortable.

The code that Jay provided did not error out, but it appeared to do nothing.
Please see my reply to his post.

Thank you all for all of your assistance.

Best Regards,

Steve McCain

fumei via OfficeKB.com said:
Oh, and Steve, Jay's comment:

"If you get here without problems, congratulations! "

is not, I believe, meant in any sarcastic way (I do not think I have ever
seen Jay be sarcastic). It is a reality comment. As you can see, the
reality to accomplish what you are asking for is do-able, but for sure it is
not trivial. Congratulations would indeed be in order if you got it to work
as you imagine without problems.

It is a worthwhile project to attempt. You would definitely increase your
understanding immensely.
Jay.....loved your response. It made me laugh and feel awed at the same time.

Not only did you give a full and detailed response (with references), but you
(hopefully) demonstrated to the OP how sometimes what may seem "simple" can
be quite complex. Of course, in some situations, the reverse is true. What
may seem complex is actually quite simple...although that does not happen
often enough. LOL.

I particularly liked your comment:

"To make the needed changes, first make a list (on paper!) of the words and
their definitions."

Indeed. Things work much better when we do a bit of writing things out on
paper beforehand.

Bravo. Great response.
What I am wanting to accomplish is this:
[quoted text clipped - 157 lines]
If you get here without problems, congratulations! Otherwise, post a reply.
 
J

Jay Freedman

That's high praise. Thank you!

--
Regards,
Jay Freedman
Microsoft Word MVP
Email cannot be acknowledged; please post all follow-ups to the newsgroup so all
may benefit.
 
S

Steve

Jay,

I got my project working, thanks to you. I cannot thank you enough.
I did have to make a couple of minor changes to the code as follows:

I had to add "autoexec" to Document, Open. (without the quotes)
I removed the Lcase parameter because my filenames are not lowercase.
I removed the check for column 1 because I have a three column table.

Everything works like a champ.

I hope you have a great evening.

Best Regards,

Steve
 
J

Jay Freedman

That's great! I love it when something works. :)

A couple of clarifications:

- The AutoExec macro should run whenever you make the template an add-in to a
document by using the Tools > Templates & Add-Ins dialog; or if you store the
template in the Startup folder (listed in the Tools > Options > File Locations
dialog), AutoExec will run once while Word is starting and won't need to be run
again during that session. In either case, you shouldn't need to call AutoExec
from the Document_Open procedure.

- The idea of the LCase function is to take the actual filename (which could be
in upper, lower, or mixed case) and return a copy that's all lower case, which
can then be compared to a constant string that's all lower case. For example, if
the actual filename is MyWeirdDoc.DOC and you tried to compare that to the
constant string "myweirddoc.doc", the condition would be false because the
comparison is case-sensitive. But if you compared LCase("MyWeirdDoc.DOC") to
"myweirddoc.doc", the condition would be true. This is advisable if you don't
know with absolute certainty what case the actual filename will have.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top