Hi,

An old topic revisited.

I've done a little work on this since the last posting- mostly for checking grammar as well as spelling- but text form fields which are protected will now not be checked, But I've still got a problem.

If a spelling correction is suggested, Word displays the context of the form field being checked. They can then overtype some of the "protected" part of the form.

Any suggestions please?

Thanks

<pre>Option Explicit

Dim Cancelled As Boolean, MyRange As Range, CorrectedError As String
Dim lngErrorCount As Long

Sub CheckSpellingAndGrammar()

Dim oDoc As Document, oSection As Section, OriginalRange As Range

'If no documents open, quit macro
If Documents.Count = 0 Then
Exit Sub
End If

Set oDoc = ActiveDocument
Set OriginalRange = Selection.Range

'Check what type of protection - if any - has been applied
Select Case oDoc.ProtectionType
'If protected for tracked changes, or if not protected,
'run spellchecker and quit
Case wdNoProtection, wdAllowOnlyRevisions
If Options.CheckGrammarWithSpelling = True Then
' Check both grammar and spelling
ActiveDocument.CheckGrammar
Else
ActiveDocument.CheckSpelling
End If
If oDoc.Range.SpellingErrors.Count = 0 Then
MsgBox "The spelling and grammar check is complete"
End If
Exit Sub
Case wdAllowOnlyComments
'Don't want to run spellchecker if protected for comments
Exit Sub
End Select

System.Cursor = wdCursorWait

'If we've got this far, it's protected for forms
'Now unprotect the document
oDoc.Unprotect
oDoc.SpellingChecked = False
lngErrorCount = 0
'Check each section for its protection property -
'which you can get even afer unprotecting the document.
'If the section was protected, call a subroutine to spellcheck the formfields
'if it wasn't, spellcheck the section
StatusBar = "Spellchecking document ..."
For Each oSection In oDoc.Sections
If oSection.ProtectedForForms Then
Call CheckProtectedSection(oSection)
If Cancelled Then
'Boolean variable returned by CheckProtectedSection
'procedure if user pressed Cancel buttoon
Exit For
End If
Else
If oSection.Range.SpellingErrors.Count > 0 Or _
(Options.CheckGrammarWithSpelling And _
oSection.Range.GrammaticalErrors.Count > 0) Then
Application.ScreenUpdating = True
oSection.Range.CheckSpelling
If oSection.Range.SpellingErrors.Count > 0 Or _
(Options.CheckGrammarWithSpelling And _
oSection.Range.GrammaticalErrors.Count > 0) Then
'User pressed Cancel button
'(Pressing Ignore reduces the count, pressing Cancel doesn't)
Exit For
End If
End If
End If
Next oSection

'Re-protect the document
oDoc.Protect Type:=wdAllowOnlyFormFields, noreset:=True
OriginalRange.Select
System.Cursor = wdCursorNormal
Cancelled = False
CorrectedError = vbNullString
Set MyRange = Nothing
If lngErrorCount = 0 Then
MsgBox "The spelling and grammar check is complete"
End If

End Sub


Private Sub CheckProtectedSection(oSection As Section)

Dim FmFld As FormField

'check only the text formfields,
'don't check listboxes and checkboxes - this speeds up the code
Application.ScreenUpdating = False
For Each FmFld In oSection.Range.FormFields
'Check to see if the field is a text formfield
If FmFld.Type = wdFieldFormTextInput Then
'Check if the field is a 'real' text field (no date, formula etc)

If FmFld.TextInput.Type = wdRegularText And FmFld.Enabled Then
FmFld.Range.NoProofing = False
FmFld.Range.SpellingChecked = False
FmFld.Range.GrammarChecked = False

'Change the language constant in the following line if necessary;
'when you type the = sign, a list of all supported language constants will
'appear, and you can choose one from the list.
FmFld.Range.LanguageID = wdEnglishAUS 'Or whichever is appropriate for you

'If the current form field contains errors, spellcheck the text in it
If FmFld.Range.SpellingErrors.Count > 0 _
Or (Options.CheckGrammarWithSpelling And _
FmFld.Range.GrammaticalErrors.Count > 0) Then
'Set a range to the formfield's range in case the user
'accidentally destroys the formfield by overtyping its entire contents
Set MyRange = FmFld.Range
Application.ScreenUpdating = True
lngErrorCount = lngErrorCount + 1

If FmFld.Range.SpellingErrors.Count > 0 Then
FmFld.Range.CheckSpelling
End If
If Options.CheckGrammarWithSpelling And _
FmFld.Range.GrammaticalErrors.Count > 0 Then
FmFld.Range.CheckGrammar
End If

If IsObjectValid(FmFld) Then
If FmFld.Range.SpellingErrors.Count > 0 Or _
(Options.CheckGrammarWithSpelling And _
FmFld.Range.GrammaticalErrors.Count > 0) Then
'User pressed Cancel button
'(Pressing Ignore reduces the count, pressing Cancel doesn't)
Cancelled = True
Exit Sub
End If
Else
'If formfield was destroyed because the user overtyped its entire contents
CorrectedError = MyRange.Text
If Len(CorrectedError) = 0 Then
CorrectedError = MyRange.Words(1).Text
End If
Do While Not IsObjectValid(FmFld)
'If formfield was destroyed when the user corrected the spelling,
'reinstate it, and put the user's correction into its result
ActiveDocument.Undo
Loop
FmFld.Result = CorrectedError
End If
Application.ScreenUpdating = False
End If
End If
End If
Next FmFld

End Sub
</pre>