View Single Post
  #8   Report Post  
Posted to microsoft.public.excel.programming
Nick Nick is offline
external usenet poster
 
Posts: 8
Default Help speeding up my code

The idea of checking for a vowel before spellchecking will probably
yield the best performance increase. Thanks.

John Coleman wrote:
"If word like "A*Z" " isn;t similar to spell checking - it was just a
random boolean condition designed to *replace* spell checking to
confirm that it was in fact spell checking which was the bottle neck.

Here is my attempt at a tweak, featuring a rare appearance of a GoTo:

Sub MakeWordList()
Dim i As Long, j As Long, k As Long, l As Long
Dim letters As Variant, word As String
Dim R As Range, counter As Long
Application.ScreenUpdating = False

Range("A:A").ClearContents
Set R = Range("A1")
For i = 65 To 90
For j = 65 To 90
If j = i Then GoTo continuej
For k = 65 To 90
If k = j Or k = i Then GoTo continuek
For l = 65 To 90
If l = k Or l = j Or l = i Then GoTo continuel
word = Chr(i) & Chr(j) & Chr(k) & Chr(l)
If HasVowels(word) Then
If Application.CheckSpelling(word) = True Then
R.Offset(counter).Value = word
counter = counter + 1
End If
End If
continuel:
Next l
continuek:
Next k
continuej:
Next j
Next i
Application.ScreenUpdating = True

End Sub

Function HasVowels(S As String) As Boolean
HasVowels = (S Like "*A*") Or (S Like "*E*") Or _
(S Like "*I*") Or (S Like "*O*") Or _
(S Like "*U*") Or (S Like "*Y*")
End Function

I was assuming at first that you wanted English words and not
abbreviations -but the Excel SpellCheck allows for all sorts of
non-word abbreviations like ABMS (for American Board of Medical
Specialies). If you want these - then my HasVowels function doesn't
really make sense (why include such things only when they have a
vowel?) and should be removed. If you don't want such abbreviations-
you need something other than the default dictionary.

The above code only assembles potential words when they have no repeats
- so you only need to look at 26*25*24*23 rather than 26^4. Also - if
you are happy throwing away the ones without vowels, it saves an
additional 20*19*18*17 calls to Application.CheckSpelling.

HTH

-John

Nick wrote:
Yes, I knew that the vast majority of the time is spent on the
CheckSpelling(word) part. I had also thought about checking for
duplicated letters as the loops played out (as suggested) but hadn't
thought hard about how to do that. I can see where that would save some
time. Going and getting a word list would have made the exercise moot,
and the goal was to generate the list, not just go download it.

John, I'm not sure how "If word like A*Z Then" would be similar to
spell checking. At some point in the process I have to make sure the
word is in the Office dictionary. Do you know a way of cutting out some
of the generated "words" prior to checking them against the
spellchecker?

John Coleman wrote:
The problem is the line

If Application.CheckSpelling(word) = True Then

No amount of tweaking can help if the algorithm involves calling it
hundreds of thousands of times (which you would have to do even if you
try optimizations like only testing strings that have at least one
vowel). Over 99% of the execution time is taken up in evaluating that
condition. To see this, replace

If Application.CheckSpelling(word) = True Then

By (for example)

If word Like A*Z Then

And your code should take mere seconds to execute (I don't know about
*your* code - but I had a similar speed up in my failed attempt to
tweak your code - you should see something similar). I don't know what
the problem with CheckSpelling is - but it isn't very useful for large
collections of words.

If you have already run this code once - why not write the results to a
text file which you can open when needed?

HTH

-John Coleman