PDA

View Full Version : Problem closing only active document



sailordickie
03-28-2010, 04:21 PM
Hi please help.... I have written the following code and I want the program to close the just the document created from the template but not MS Word.... Any suggestions? (Code in blue font below where error is happening)

Option Explicit
Dim Cancelled As Boolean, myRange As Range, CorrectedError As String, oDoc As Document
Dim oSection As Section, OriginalRange As Range, newname As String, str1 As String
Dim ck As Boolean

Private Sub cmdSaveExit_Click()

'Unprotect the file
If ActiveDocument.ProtectionType <> wdNoProtection Then
ActiveDocument.Unprotect Password:="sfu"
End If

Application.ScreenUpdating = False
With ActiveDocument

'checks to see if user wants to update any fields

If txt_brief_num.Value = "" Then
Else
UpdateBookmark "brief_num", txt_brief_num.Value
End If

If txt_witness_name.Value = "" Then
Else
UpdateBookmark "witness_name", txt_witness_name.Value
End If

If txt_witness_title.Value = "" Then
Else
UpdateBookmark "witness_title", txt_witness_title.Value
End If

If txt_author_name.Value = "" Then
Else
UpdateBookmark "author_name", txt_author_name.Value
End If

If txt_author_phone.Value = "" Then
Else
UpdateBookmark "author_phone", txt_author_phone.Value
End If

If txt_version_date.Value = "" Then
Else
UpdateBookmark "version_date", txt_version_date.Value
End If

End With
Application.ScreenUpdating = True


'Reprotect the document.
If ActiveDocument.ProtectionType = wdNoProtection Then
ActiveDocument.Protect _
Type:=wdAllowOnlyFormFields, NoReset:=True, Password:="sfu"
End If
'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
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
oDoc.Unprotect Password:="sfu"
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
oDoc.Protect Type:=wdAllowOnlyFormFields, NoReset:=True, Password:="sfu"
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
' SaveBrief Macro
Dim ck As Boolean
If newname = "" Then
str1 = "Enter New File Name Here"
Else
str1 = newname
End If
ck = Application.Dialogs(wdDialogFileSaveAs).Show(str1)
If ck = True Then
newname = ActiveDocument.Name
End If
' Close active document

Set oDoc = ActiveDocument
With oDoc
.AttachedTemplate.Saved = True
.Close wdDoNotSaveChanges
End With

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 = wdEnglishUS
'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

Private Sub TurnNoProofingOff(FmFld As FormField)
'This subroutine is called only in Word 2000 and above
FmFld.Range.NoProofing = False
End Sub
Private Sub Word97TableBugWorkaround(FmFld As FormField)
'Unlink formfield (convert to text)
Set myRange = FmFld.Range
FmFld.Range.Fields(1).Unlink
Application.ScreenUpdating = True
myRange.CheckSpelling
If myRange.SpellingErrors.Count > 0 Then
'User pressed Cancel button
'(Pressing Ignore reduces the count, pressing Cancel doesn't)
Cancelled = True
End If
CorrectedError = myRange.Text
'Undo to reinstate the formfield
Do While Not IsObjectValid(FmFld)
oDoc.Undo
Loop
FmFld.Range.Fields(1).Result.Text = CorrectedError
Application.ScreenUpdating = False
End Sub
Sub UpdateBookmark(BookmarkToUpdate As String, TextToUse As String)
Dim BMRange As Range
Set BMRange = ActiveDocument.Bookmarks(BookmarkToUpdate).Range
BMRange.Text = TextToUse
ActiveDocument.Bookmarks.Add BookmarkToUpdate, BMRange
End Sub

Chief Gopher
03-29-2010, 03:21 AM
try using
ActiveDocument.Close

in place of .Close wdDoNotSaveChanges

fumei
03-29-2010, 08:35 AM
And why are you using Set oDoc = ActiveDocument twice? It is already Set.

Also, you have With statement you do not need.
With ActiveDocument
'checks to see if user wants to update any fields
If txt_brief_num.Value = "" Then
Else
UpdateBookmark "brief_num", txt_brief_num.Value
End If

If txt_witness_name.Value = "" Then
Else
UpdateBookmark "witness_name", txt_witness_name.Value
End If

etc.
The instructions are a Call. You do not need the With. Further, as you have no instruction for the True return (= ""), you can do it checking it it is NOT "", like this:
'checks to see if user wants to update any fields
If txt_brief_num.Value <> "" Then
UpdateBookmark "brief_num", txt_brief_num.Value
End If

If txt_witness_name.Value <> "" Then
UpdateBookmark "witness_name", txt_witness_name.Value
End If


Lastly: "Code in blue font below where error is happening"

Precisely what error are you getting?

sailordickie
03-29-2010, 08:09 PM
Thanks all have removed with statement and modified code as suggested

Error I get is Run-time error '4198': Command Failed

I am using Word 2002

Thanks heaps for all help - I am a beginner at VBA so all comments and suggestions appreciated

fumei
03-30-2010, 08:35 AM
Usually that error is because of a state of the current activedocument. It is a difficult error to figure out. I have not parsed through every line of your code, but as it stands I can not see why you would get that error.

sailordickie
03-30-2010, 10:16 PM
Bump - Help anyone?!?!? Deadline is nearing and I need to resolve this issue.

Thanks in advance

macropod
03-31-2010, 12:01 AM
Hi sailordickie,

Are any Word dialogues open when you're trying to close the document? If so, you should close them - completing/cancelling whatever action they were opened for.

sailordickie
03-31-2010, 03:44 PM
The user form (Dialogue Box) is still open do I need a line of code to close this after the fields have been updated if needed? If so what code should I use? User form is named frmUpdateBriefDetails

Thanks!

macropod
03-31-2010, 08:46 PM
Hi sailordickie,

Not your userform, but a Word dialogue box. Also, since you're using formfields you shouldcheck that you aren't trying to do something while the document is protected that can only be done when it is unprotected (eg setting ActiveDocument.ShowSpellingErrors = True or
ActiveDocument.ShowGrammaticalErrors = True or trying to copy something to/from a protected Section). I haven't studied you code for any such issues.

sailordickie
03-31-2010, 09:58 PM
Just tested and no other dialogue boxes appear to be open.

The document does get protected and unprotected a couple of times once for updating the form fields and the other for spell checking maybe this is causing the error???

fumei
04-01-2010, 11:50 AM
Yup, it is the spellchecking.


If oDoc.Range.SpellingErrors.Count


Try fiddling with your protect timing.

macropod
04-02-2010, 04:38 PM
Hi sailordickie,

Just an observation - there's probably no reason to spellcheck any text outside the formfields, so mark that text as 'no proofing'.