Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Deleting a misspelling .. using Word Automation

Status
Not open for further replies.

FoxEgg

Programmer
Mar 24, 2002
749
AU
Hi all

I have written a simple program to solve a newspaper puzzle... the 9 letter scramble.

It simply runs through all the 9 factorial combinations... and it generates millions of letter combinations.

I write the generated 'word' to a Word document using a simple word automation ... and 100's of pages are written... and word does a spell check on them... and of course most are random letter combinations.

Question: Is there any (dare I say simple) way of

1. writing the Word document (<-- this I have done)
2. checking the misspelling (<-- this Word does automatically)
3. deleting any misspelling immediately (<-- what I want Word to do)

I hope that this is a post that should be elsewhere...

This is the code I use to generate Word document.

Code:
Public oWord,oselection,odoc
oWord = Createobject("word.application")
odoc = oWord.documents.Add
oselection = oWord.Selection
With oselection
    .TypeText(randomstring)
Endwith
oWord.Visible = .T.

Thanks
Fox Egg
 
For starters, don't use .TypeText(). :) I know it's what the macro recorder uses, but it's baby-talk for real useful programming.

Instead, set the .Text property. That leaves the selection "selected", so you can then use the .Delete method:

Code:
With oselection
     .Text=randomstring
     * do whatever
     .Delete
Endwith

If you're going to do anything with automation, you owe it to yourself to get this book:

 
FoxEgg,

May I suggest a slightly different approach - one that you should find easier.

Instead of writing out the text to a document, spellcheck the individual words. The point is that Word has two spell check methods:
[ul]
Call the document's CheckSpelling method to check an entire document; this is done interactively, with the user reviewing each word in turn; or
[/ul]
[ul]

[/ul]
[ul]
Call the application's CheckSelling method to check an individual word; this returns .T. or .F., depending on whether or not the spelling is correct.
[/ul]

My suggest is that you use the second of the above. Don't bother to write the text out to a document. Just call the method in a loop, something like this:

Code:
DO WHILE <there are still words to check>
  lcWord = <the next word to check>
  IF oWord.CheckSpelling(lcWord)
    * The word is valid
  ELSE
    * The word is not valid
  ENDIF
ENDFOR

Be aware that this code will be very slow, as each call to the method will involve some overhead. But you can always add a progress bar to help you judge the time to completion.

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips, training, consultancy
 
Mike has been faster than my googling. I knew I also had done this without writing text to a document, you can directly call loWord.CheckSpelling(sWord), you can even add usage of a custom dictionary (.dic file).

Code:
oWord = CreateObject("Word.Application")
? oWord.CheckSpelling("This is a sentence.")
? oWord.CheckSpelling("word")

You can also use SpellingSuggestions to find out, if a word's spelling is correct.

Code:
oWord = CreateObject("Word.Application")
? oWord.GetSpellingSuggestions("word").Count
? oWord.GetSpellingSuggestions("worrd").Count

If the count is >0 you find suggested words via:
Code:
loSuggestions = loWord.GetSpellingSuggestions("Wurd")
For each loSuggestion In loSuggestions
   ? loSuggestion.Name
EndFor

Besides that, Craig S. Boyd has done a spell checker with a dictionary in native VFP, google vfp spellchecker, and you'll find that. Look out for SPS Blog search results.

Bye, Olaf.
 
I forgot to mention, for unknown reasons oWord.GetSpellingSuggestions() needs an active document opened, otherwise it errors "This command is not available..."
Just create a new empty doc via oWord.Documents.Add() before using GetSpellingSuggestions().

Bye, Olaf.
 
Some more suggestions to speed up the unscrambling of letters to a word:
1. GetSpellingSuggestions will help you to find the word, even if your input is wrong but near to the correct spelling
2. vowels and consonants typically are spread in a word, so you can avoid to check a lot of permutations of the letters with more than 3 or 4 consonants in a row.
3. the perhpas best thing is to feed he letters to an annagram finder. That will work the same way with scrambled letter as with the letters of an initial word. It finds words composed of the letters and for that matter would eg have a reverse lookup table, in which alphabetical ordered letters point to the words you can build from them, eg "arw" will point to the words "raw" and "war".

Using a dictionary table as of craig boyd's spell checker you can easily build up such a reverse lookup dictionary by taking each word, sorting it's letters and store those sorted words to point to the real words. Then you can also sort the scrambled letters of your newspaper crossword puzzle and lookup the sorted letters to find the words, which can be written with them.

Bye, Olaf.
 
There's a completely different method of attacking this sort of problem. Instead of generating every possible combination of letters, and then checking each combination against the dictionary, you can do it the other way round. Loop through the dictionary, checking to see of each word contains the required combination of letters.

Whether that's faster or not will depend on the number of letters involved.

Unfortunately, I don't know any way of looping through the dictionary in Word, but it might be possible with other dictionaries.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips, training, consultancy
 
You can take this anagram generator and feed in the letters as the anagram parameter to find valid single words (d=1). Rais d value to get 2 or more words from the initial letters...

arw&language=english&t=100&d=1&include=&exclude=&n=&m=&source=adv&a=n&l=n&q=n&k=0

I once did program an anagram finder myself, I may look, if I find it's source code ro share that here.

Bye, Olaf.
 
Wow !.... Thanks so much... I haven't tried the suggestions yet... but I will.

FIRST.. I have bought the book... (and several other books unrelated that I was easily seduced into purchasing)

NEXT

I thought you might like to have a laugh at my code... It includes the frustrating letter jumble that started my thought process... Don't laugh too loud or too much. I am a surgeon, at least I have an excuse.

Code:
counter = 1
dimension larray[9]

set escape on
set console off
set talk on
clear
LARRAY[1] ="L"
LARRAY[2] ="O"
LARRAY[3] ="V"
LARRAY[4] ="R"
LARRAY[5] ="W"
LARRAY[6] ="R"
LARRAY[7] ="E"
LARRAY[8] ="I"
LARRAY[9] ="T"

Public oWord,oselection,odoc
oWord = Createobject("word.application")
odoc = oWord.documents.Add
oselection = oWord.Selection



for I = 123456789 to 987654321 step 1

set cons off
istring = alltrim(str(I))

do while at("0", istring) = 0 .and. at("1", istring, 2) = 0 .and. at("2", istring, 2) = 0 .and. at("3", istring, 2) = 0 .and. at("4", istring, 2) = 0 .and. at("5", istring, 2) = 0 .and. at("6", istring, 2) = 0 .and. at("7", istring, 2) = 0 .and. at("8", istring, 2) = 0 .and. at("9", istring, 2) = 0

*if at("1", istring, 2) = 0 && means there is no *second occurance of 1 then is OK to continue

set cons off
counter = counter + 1
IF counter = 100  && I wanted to reduce the number printed to 1 in a hundred

set cons off
LL1 = substr(istring, 1,1)
LL2 = substr(istring, 2,1)
LL3 = substr(istring, 3,1)
LL4 = substr(istring, 4,1)
LL5 = substr(istring, 5,1)
LL6 = substr(istring, 6,1)
LL7 = substr(istring, 7,1)
LL8 = substr(istring, 8,1)
LL9 = substr(istring, 9,1)

HIDDEN = LARRAY[val(LL1)]+LARRAY[val(LL2)]+LARRAY[val(LL3)]+LARRAY[val(LL4)]+LARRAY[val(LL5)]+LARRAY[val(LL6)]+LARRAY[val(LL7)]+LARRAY[val(LL8)]+LARRAY[val(LL9)]
set cons on
??HIDDEN+ "  "
set cons off
With oselection
    .Font.Size=12
    .TypeText(LOWER(hidden)+"  ")
   
Endwith
oWord.Visible = .T.


ELSE
ENDIF

IF counter =>100
counter = 1
ENDif

set cons off
exit
enddo
***
set cons off

endfor

My code works... in part... up to the point of generating 10000's + of words ...

Thanks to all... I will get around to trialling out your solutions... and then I cannot wait to cheat all my surgical and anaesthetic colleagues in the surgeons tea room at coffee break... and demonstrate my SUPER POWERS of Newspaper 9 letter letter jumble solving. (You see... They always beat me to the solution... possibly because they are smarter ... but most probably because I am burdoned by being an orthopaedic type surgeon ..you know the type --> strong as an ox, twice as smart... able to bench press my IQ... you can only imagine the insults that I get)

BUT NOT FOR LONG !!!

Ha ha ha ha (<-- wicked laugh with echo ... if only there was an echo function on Tek-Tips)

Soon I will be emboldened to kick sand in their face!


FoxEgg

I am not entirely sure that solving anagrams was the lofty intention of the creators of foxpro... but I need all the help I can get.
 
Good luck with this, FoxEgg. And let us know how things go.

But please try to put it out of your mind while you are in the operating room. I'd hate to you to be worrying about anagrams and Office automation while doing a hip replacement. (Just kidding, of course. I know this is all just a coffee break thing for you.)

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips, training, consultancy
 
The anagram finder should solve your problem indeed.

In regard to your code, let me pick out some points:

1. While construct with Exit:

Code:
Do While ...
  ...
  Exit
EndDo

I assume you started with some while loop and then added the FOR loop later around this. That constrcut with a WHILE loop ending with an EXIT is equal to an IF..ENDIF.

Code:
If at("0", istring) = 0 .and. ...
   ...
Endif

The test for no double digit is okay, but slow. Even just the test for the majority of wrong permutations takes much longer than initially creating the permuations by swapping positions of an initial number or beter yet of the initial scrambled letters array.

You can make use of recursion for that matter. Just use a string of the nine letters, not an array. You can then easily swap letter positions via substr() (read char) and stuff() (write char).

You find some general ideas to generate permuations here: [URL unfurl="true"]http://www.technicalinterviewquestions.net/2008/12/algorithm-permutations-string.html[/url]

and here in the fox wiki:
[link fox.wikis.com/wc.dll?Wiki~PermutationsAndCombinations][/url]

And also here at tek-tips I wrote something about the topic already:
[URL unfurl="true"]http://www.tek-tips.com/viewthread.cfm?qid=974823[/url]

Bye, Olaf.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top