MS Office Forum / Word / Programming / January 2006
Userform to display index marked { XE"..." } fields
|
|
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.
|
|
|