Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
DiscussionsAccessExcelInfoPathOutlookPowerPointPublisherWord
DirectoryUser Groups
Related Topics
Outlook ExpressInternet ExplorerWindowsMS Server ProductsMore Topics ...

MS Office Forum / Word / Programming / January 2006

Tip: Looking for answers? Try searching our database.

Userform to display index marked { XE"..." } fields

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
julianv - 05 Jan 2006 16:05 GMT
I am a reasonably competent word user, but new to VBA. I index words a lot in
my documents and I want to design a simple userform that has a listbox which
shows all the words which as index marked in { XE"..." } fields.

I have got so far as the design of the box, but can't find any information
online as to how to link the listbox to the list of words marked in { XE"..."
} fields.

Can anyone help?
Greg - 05 Jan 2006 17:41 GMT
Julian,

I used this process:

Find all of the indexed words and add to an array.
Sort the array alphabelically
Add the contents of the sorted array to the ListBox

I created a UserForm and named it frmIndexEntries

Call the UserForm with something like this:

Sub CallUserForm()
Dim myFrm As frmIndexEntries
Set myFrm = New frmIndexEntries
myFrm.Show
Unload myFrm
Set myFrm = Nothing
End Sub

Here is the code for the UserForm (Note it is simply a listbox to list
the indexed items and a command button to hide the form)

Option Explicit
Const cNoValue = -2
Private Sub CommandButton1_Click()
Me.Hide
End Sub
Private Sub UserForm_Initialize()
Dim oField As Field
Dim tmpString As String
Dim MyArray() As String
Dim i As Long
Dim a As Integer
Dim z As Integer
i = -1
'Find all the index entries and put into an array
For Each oField In ActiveDocument.Fields
 If oField.Type = wdFieldIndexEntry Then
   i = i + 1
   tmpString = Mid(oField.Code.Text, 6)
   tmpString = Left(tmpString, InStr(tmpString, """") - 1)
   ReDim Preserve MyArray(i)
     MyArray(i) = tmpString
 End If
Next
'Sort array alphabetically
a = LBound(MyArray)
z = UBound(MyArray)
QuickSort MyArray, a, z
'Build the sorted ListBox
For i = 0 To UBound(MyArray)
 Me.ListBox1.AddItem (MyArray(i))
Next
End Sub
Public Sub QuickSort(MyArray As Variant, _
   Optional iLeft As Integer = cNoValue, _
   Optional iRight As Integer = cNoValue)

Dim iVarA As Integer
Dim iVarB As Integer
Dim vTest As Variant
Dim iMid As Integer

If iLeft = cNoValue Then iLeft = LBound(MyArray)
If iRight = cNoValue Then iRight = UBound(MyArray)
If iLeft < iRight Then
 iMid = (iLeft + iRight) \ 2
 vTest = MyArray(iMid)
 iVarA = iLeft
 iVarB = iRight
 Do
   Do While MyArray(iVarA) < vTest
     iVarA = iVarA + 1
   Loop
   Do While MyArray(iVarB) > vTest
     iVarB = iVarB - 1
   Loop
   If iVarA <= iVarB Then
     Swap MyArray, iVarA, iVarB
     iVarA = iVarA + 1
     iVarB = iVarB - 1
   End If
 Loop Until iVarA > iVarB
 If iVarB <= iMid Then
   Call QuickSort(MyArray, iLeft, iVarB)
   Call QuickSort(MyArray, iVarA, iRight)
 Else
   Call QuickSort(MyArray, iVarA, iRight)
   Call QuickSort(MyArray, iLeft, iVarB)
 End If
End If
End Sub
Private Sub Swap(vItems As Variant, iItem1 As Integer, _
                iItem2 As Integer)
Dim vTemp As Variant
vTemp = vItems(iItem2)
vItems(iItem2) = vItems(iItem1)
vItems(iItem1) = vTemp
End Sub

The challenge of course was to get the only the actual "word" text out
of the index entry field.  The rest of the sort and build stuff was
from a similiar project that Jay Freedman helped me with last year.

I am just a casual VBA user and so always welcome suggestions for
improvement on all I manage to cobble together.

HTH
julianv - 05 Jan 2006 19:42 GMT
Greg,

First, many thanks for you reply.

I have created a userform in the normal template (I renamed it UserForm1 for
convenience).

I added to the form ListBox1 and CommandButton1 by using the toolbox, but
did not amend any properties of these items.

I inserted
"Sub CallUserForm()
Dim myFrm As UserForm1
Set myFrm = New UserForm1
myFrm.Show
Unload myFrm
Set myFrm = Nothing
End Sub"
in my "new macros" section of the normal.dot document template and added a
button linked to the macro  onto one of my toolbars.

----
so far, so good - up to this point, the whole process works fine - I can
click on the macro button and the userform will appear.
----

When I then add the code into the Userform coding area (by right-clicking on
the Userform and cutting and pasting the remaining selection into the coding
area), the macro button no longer visibly opens the form, although it does
appear to execute its routine.

Is there something I am missing?

> Julian,
>
[quoted text clipped - 105 lines]
>
> HTH
julianv - 05 Jan 2006 20:47 GMT
Greg,

I have been playing around with the code and by switching the
WordFieldIndexEntry to WordFieldIndex, I managed to identify the fact that
the code works fine - so then I knew it must be something different, so I
then started to try adjusting the numbers of the Mid and Left values in the
code.

The following work best - although I am not sure why.

   tmpString = Mid(oField.Code.Text, 4)
   tmpString = Left(tmpString, InStr(tmpString, """") + 150)

I note that the lower case alpha gets listed at the bottom of the upper case
alpha section - is there a way to integrate the two?

Thanks for your help.

- Julian

> Greg,
>
[quoted text clipped - 138 lines]
> >
> > HTH
Greg Maxey - 05 Jan 2006 23:34 GMT
Julian,

Are you referring to this line?

If oField.Type = wdFieldIndexEntry Then

I don't know what WordFieldIndex is.  There is wdFieldIndex and
wdFieldIndexEntry.  If I try to use wdFieldIndex then I do get strange
results, because I one to process each in  IndexEntry not the Index field
itself.

While I don't see how your code is working, I now see that mine fell short
as I was only testing with very short index entries.  Again the challenge
was to isoloate the text in the field code like { XE "Engines" }.  I think
this will work:

Private Sub UserForm_Initialize()
Dim oFld As Field
Dim oRng As Range
Dim endPos As Integer
Dim startPos As Integer
Dim tmpString As String
Dim MyArray() As String
Dim i As Long
Dim a As Integer
Dim z As Integer
i = -1
'Find all the index entries and put into an array
For Each oFld In ActiveDocument.Fields
 If oFld.Type = wdFieldIndexEntry Then
   i = i + 1
   Set oRng = oFld.Code
   startPos = 6 'The first character after the " in the field code
   endPos = InStr(startPos + 1, oRng, """", 1)
   tmpString = Mid(oRng, startPos, endPos - startPos)
   ReDim Preserve MyArray(i)
   MyArray(i) = tmpString
 End If
Next
'Sort array alphabetically
a = LBound(MyArray)
z = UBound(MyArray)
QuickSort MyArray, a, z
'Build the sorted ListBox
For i = 0 To UBound(MyArray)
 Me.ListBox1.AddItem (MyArray(i))
Next
End Sub

There will be a problem if the index entry itself contains quotation marks.

As for the integrating the sort, you can add Lcase method (I think method is
the right term) to the quick sort routine.

Public Sub QuickSort(MyArray As Variant, _
   Optional iLeft As Integer = cNoValue, _
   Optional iRight As Integer = cNoValue)

Dim iVarA As Integer
Dim iVarB As Integer
Dim vTest As Variant
Dim iMid As Integer

If iLeft = cNoValue Then iLeft = LBound(MyArray)
If iRight = cNoValue Then iRight = UBound(MyArray)
If iLeft < iRight Then
 iMid = (iLeft + iRight) \ 2
 vTest = LCase(MyArray(iMid))
 iVarA = iLeft
 iVarB = iRight
 Do
   Do While LCase(MyArray(iVarA)) < vTest
     iVarA = iVarA + 1
   Loop
   Do While LCase(MyArray(iVarB)) > vTest
     iVarB = iVarB - 1
   Loop
   If iVarA <= iVarB Then
     Swap MyArray, iVarA, iVarB
     iVarA = iVarA + 1
     iVarB = iVarB - 1
   End If
 Loop Until iVarA > iVarB
 If iVarB <= iMid Then
   Call QuickSort(MyArray, iLeft, iVarB)
   Call QuickSort(MyArray, iVarA, iRight)
 Else
   Call QuickSort(MyArray, iVarA, iRight)
   Call QuickSort(MyArray, iLeft, iVarB)
 End If
End If
End Sub

HTH

Signature

Greg Maxey/Word MVP
See:
http://gregmaxey.mvps.org/word_tips.htm
For some helpful tips using Word.

> Greg,
>
[quoted text clipped - 165 lines]
>> >
>> > HTH
Greg - 05 Jan 2006 20:58 GMT
julianv,

I don't know why it isn't working.

You say that is does appear to execute its routing, what do you mean?
If you don't see the form on the screen how do you know it is loading a
sorted list of index entries in the listbox?

What happens when you step throgh the calling macro routine one line at
a time using F8?  Test on a document that only has one or two index
entries (or it will take a while).  When you get to the .Show line, the
control should shift to the the UserForm initialize event, keep
stepping through.  When the sort and build process is complete, the
control should shift back to the .Show line.  One more click of F8
should then display the form on the screen.

If you can't work it out, send you e-mail address and I will send you
my practice template with the code.
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.