PDA

View Full Version : Error Handling for a Bad password error in Word (VBA)



AndyB3004
09-15-2010, 03:40 AM
Greetings, I'm hoping someone on here can possibly assist me.

I have two large sets of protected forms which are opened via the same portal.
As they are protected for 'Form fields the Spell check is disabled & I very much want the Spell check enabled. To this end I have developed a custom toolbar button which will be rolled out to all users Word startup folder, thus adding it to their default tools.

what it currently does is it initiates a popup asking 'form type 1 or 2?' and dependant on their response is whether it performs the unlock & spell check & re-lock using password 1 or 2.
The only issue there is that sometimes users might not know which system hosts the form (because they're opened through the same portal in Word), so they might press the wrong one, getting a 'Bad Password' error. whilst some may thereafter try the other button, many may not and this could lead to the tool not being as effective as it could be.
What I'm looking to do ( & I'm presuming it's possible) is to use error handling, so that it tries password 1 and if it gets the Bad password error

- Runtime Error 5485 'The Password is Incorrect' -

Then it tries Password 2. Thereby negating the need for the ugly popup, or any interaction from the Users.

Does anyone have any idea of the commands that I need to use to get this to work? (I think it's ON_Error?)

Esssentially I suppose I'm asking how do I get the code to recognise that Error 5485 has occurred and then to perform further function(s) instead of throwing up the error

I Hope that makes Sense and if anyone thinks they can assist but needs more information, please just let me know and I'll be happy to provide,

Kind Regards, - Andy B

fumei
09-15-2010, 09:48 AM
Something is not right here.

"initiates a popup asking 'form type 1 or 2?' "

That sounds like the user types in 1 or 2. If so, then:

"so they might press the wrong one," does not make sense, as they are "pressing" what exactly?

In any case, I am not sure what the point of having ANY password is if there is an automatic VBA entered correction. Why not just make the password = ""? Problem solved. Not only that, but the user does not have to even deal with the "form 1 or 2" popup. ONE button to unprotect, do the spellcheck, and re-protect - for both forms. No popup required.

But if you insist, please post the code for the popup (is this an inputbox?).

If it is an inputbox, then it is taking the value of the inputbox, and logically applying password A.

User types in 1. Code tries with "xxxxxxx".
User types in 2. Code tries with "yyyyyy"

If file is protected with "xxxxxx", then yes, if user types in 2 trying with "yyyyyy" gets bad password error.

Simply put:
Sub ErrorTrapPassword()
On Error GoTo fixthis:
ActiveDocument.Unprotect
Exit Sub
fixthis:
If Err.Number = 5485 Then
ActiveDocument.Unprotect "gerry"
End If
End Sub
Say the document is protected with "gerry". The code tries to unprotect, and you type in "yadda". This throws an error. On Error, the code goes to fixthis: If Err.Number is 5485 (which it will be), then the correct password is used.

Adjust accordingly for your situation.

But again, I fail to see ANY reason for having a password if you are going to fix it automatically.

AndyB3004
09-16-2010, 01:22 AM
Gerry, Many thanks for your help.

I appreciate what you are saying, however to give some clarity on the situation, basically there are two libraries of forms (built in word). Theres about 2000 in total & many of them predate my involvement.
To maintain the integrity of the forms, they are all password protected for Form fields, so the users just fill out the forms, & many have buttons to attach the document as an email & address the email automatically to the right department etc.
Every user has a button on their word toolbar which grants them access to a menu of the forms, whereby they select a category & then the respective form for the function they require. In 2006 a new system came in & the decision was made to attach certain forms to that system, and a different password was used (not sure why, - it predates me).
The spell check has been something that I've wanted to get working for a while, & I've taken massive steps towards getting it done in the last few weeks, however the only way I could get around the different passwords was to have a form as described above, with two command buttons (when the user selects 'system 1 or 2'). It is those buttons which define which password is used, - and it works fine, I was just hoping to use automation to alleviate the need for the popup & the user having to press a further button.
I think the code snippet you supplied will give me something to go on.

The code I'm currently using is detailed below (system names & passwords simplified for confidentiality purposes)

Public FormType As String

Public Sub cmdFormsNo_Click()
' This is activated by the user pressing 'No' On the form 'frmSpellCheck'
' This simply sets the variable 'FormType'
FormType = "SystemA"
SpellCheck
Unload Me
End Sub
Sub cmdFormsYes_Click()
' This is activated by the user pressing 'Yes' On the form 'frmSpellCheck'
' This simply sets the variable 'FormType'
FormType = "SystemB"
SpellCheck
Unload Me
End Sub

Sub SpellCheck()
Dim oSection As Section, OriginalRange As Range
'If no documents open, quit macro
If Documents.Count = 0 Then
Exit Sub
End If
Set oDoc = ActiveDocument
'Check what type of protection - if any - has been applied
Select Case oDoc.ProtectionType
'If not protected, or if protected for tracked changes,
'run spellchecker and quit
'-------------
Case wdNoProtection, wdAllowOnlyRevisions
If Options.CheckGrammarWithSpelling Then
oDoc.CheckGrammar
Else
oDoc.CheckSpelling
oDoc.SpellingChecked = False
End If
Application.ScreenUpdating = True
Application.ScreenRefresh
If oDoc.SpellingErrors.Count = 0 Then
If Options.CheckGrammarWithSpelling Then
MsgBox "The spelling and grammar check is complete", _
vbInformation
Else
MsgBox "The spelling check is complete", vbInformation
End If
End If
System.Cursor = wdCursorNormal
Exit Sub
'-------------
Case wdAllowOnlyComments
'Don't want to run spellchecker if protected for comments
Exit Sub
End Select
Set OriginalRange = Selection.Range
System.Cursor = wdCursorWait
'-------------
'-------------
'If we've got this far, it's protected for forms
'Now unprotect the document
' Which password is used depends on the contents of the variable 'FormType'
If FormType = "SystemA" Then
oDoc.Unprotect Password:="PasswordA"
Else
oDoc.Unprotect Password:="PasswordB"
End If
oDoc.SpellingChecked = False
'Check each section for its protection property -
'which you can get even after 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 button
Exit For
End If
Else
If oSection.Range.SpellingErrors.Count > 0 Then
Application.ScreenUpdating = True
oSection.Range.CheckSpelling
If oSection.Range.SpellingErrors.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
' Which password is used depends on the contents of the variable 'FormType'
If FormType = "Word" Then
oDoc.Protect Type:=wdAllowOnlyFormFields, NoReset:=True, Password:="development"
Else:
oDoc.Protect Type:=wdAllowOnlyFormFields, NoReset:=True, Password:="rmsdevelopment"
End If
OriginalRange.Select
Application.ScreenUpdating = True
Application.ScreenRefresh
If oDoc.Range.SpellingErrors.Count = 0 Then
If Options.CheckGrammarWithSpelling Then
MsgBox "The spelling and grammar check is complete", _
vbInformation
Else
MsgBox "The spelling check is complete", vbInformation
End If
End If
'Release variables from memory
System.Cursor = wdCursorNormal
Cancelled = False
CorrectedError = vbNullString
Set MyRange = Nothing
End Sub

'--------------------------------------------------------------------------------
Private Sub CheckProtectedSection(oSection As Section)
Dim FmFld As FormField, FmFldCount As Long, Pos As Long
'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);
'and that it is enabled for text input
If FmFld.TextInput.Type = wdRegularText And FmFld.Enabled Then
'The following subroutine won't be called if Word 97 is in use
If Not Left$(Application.Version, 1) = "8" Then
Call TurnNoProofingOff(FmFld)
End If
FmFld.Range.SpellingChecked = 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 = wdEnglishUK
'Or whichever language is appropriate for you
'If the current form field contains errors, spellcheck the text in it
If FmFld.Range.SpellingErrors.Count > 0 Then
'The following condition is to allow for a Word 97 bug, which
'was fixed in 2000; (and in the latest Word 97 patches). If
'the formfield is in a table and contains more than one
'paragraph, then spellchecking it will crash Word 97
If Left$(Application.Version, 1) = "8" _
And FmFld.Range.Paragraphs.Count > 1 _
And FmFld.Range.Tables.Count > 0 Then
Call Word97TableBugWorkaround(FmFld)
If Cancelled Then Exit Sub
Else
'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
FmFldCount = oSection.Range.FormFields.Count
Application.ScreenUpdating = True
FmFld.Range.CheckSpelling
If IsObjectValid(FmFld) Then
If FmFld.Range.SpellingErrors.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 user overtyped its
'entire contents
CorrectedError = MyRange.Text
If Len(CorrectedError) = 0 Then
CorrectedError = MyRange.Words(1).Text
End If
'Formfields should really NEVER be preceded by a tab;
'design your forms so that each formfield is in its own
'table cell (removing borders as necessary). However, to
'cater for any legacy forms you may have, the following
'loop works around the possibility that it might be
'preceded by a tab
Pos = InStr(CorrectedError, vbTab)
Do While Pos > 0
CorrectedError = Mid$(CorrectedError, Pos + 1)
Pos = InStr(CorrectedError, vbTab)
Loop
'If formfield was destroyed when the user corrected the
'spelling, reinstate it, and put the user's correction into its
'result. Note that although Undo reinstates the Formfield
'itself, if the Formfield is preceded by a tab, It doesn't
'reinstate the FmFld object, hence the need to do a count
'(although, as previously stated, in a well-designed form,
'formfields should never be preceded by a tab, as it's
'better use table cells (removing borders as necessary).
Do While Not FmFldCount = _
oSection.Range.FormFields.Count
oDoc.Undo
Loop
'Also due to a Word bug, if the formfield is preceded by a
'tab, the text within the formfield may now be selected
'without the formfield itself being selected!
'Hence the following convoluted workaround
If Selection.FormFields.Count = 0 Then
Selection.MoveRight unit:=wdCharacter
Selection.MoveLeft unit:=wdCharacter, Extend:=True
End If
If Not IsObjectValid(FmFld) Then
Set FmFld = Selection.FormFields(1)
End If
FmFld.Result = CorrectedError
End If
End If
Application.ScreenUpdating = False
End If
End If
End If
Next FmFld
End Sub

I'll keep trying, utilising the advice you gave me above and If I manage to accomplish what I want I'll let you know.

Kind Regards, & Many thanks for your help.

- AndyB

fumei
09-16-2010, 10:25 AM
So let me see. Clicking NO actually means YES, but with password_X.

Clicking YES means YES, but with password_Y.

Seems very silly to me.

BOTH Yes and No executes the same thing, but with a different string variable (the password).

I will restate that if a password is automatically, programmatically used, it is a pointless password.

Yes, to use the formfields the document MUST be protected for forms. However, you can use "" as the password.

Then the users can click a "SpellCheck" button/icon whatever, and the document is spellchecked...which is what happens anyway. Then it would not matter which forms it is...which is what happens anyway.

Oh I understand that these are from the past and you likely have little control over things. Nevertheless, it seems silly to me.