G
Greg Maxey
This is a very long post. I have had fits today working with ranges
and an on exit event. My challenge (perhaps your childs play) was to
create a conditional additional question in a form.
Example:
Why did the chicken cross the road? "Dropdown field containing
multiple choices"
If the selection made above was "To get the other side" Then display a
follow-up question:
Did she say why she wanted to cross the road: "Dropdown field
containing yes and no"
I created the first question and dropdown field using "Question" as the
bookmark name.
I created the follow-up question and dropdown field using "FUA" as the
bookmark name. I then stored the follow-up question and formfield as
AutoText "FUQ."
I used a bookmark "FUQ" to designate the placement of the conditional
question.
Since the FUQ needed to be displayed or hidden depending on the
condition, I realized that I would need to write either the AutoText
FUQ or "" to the bookmark range and redefine the range with each
change.
My first coding attempt was:
Sub OnExitDropDown()
Dim oFF As FormFields
Dim oRng As Word.Range
Set oFF = ActiveDocument.FormFields
Select Case
oFF("Question").DropDown.ListEntries(oFF("Question").DropDown.Value).Name
Case Is = "Yes"
ActiveDocument.Unprotect
Set oRng = ActiveDocument.Bookmarks("FUQ").Range
oRng.Text = NormalTemplate.AutoTextEntries("FUQ")
ActiveDocument.Bookmarks.Add "FUQ", oRng
ActiveDocument.Protect wdAllowOnlyFormFields, True
Case Else
ActiveDocument.Unprotect
Set oRng = ActiveDocument.Bookmarks("FUQ").Range
oRng.Text = ""
ActiveDocument.Bookmarks.Add "FUQ", oRng
ActiveDocument.Protect wdAllowOnlyFormFields, True
End Select
End Sub
To my dismay, I realized that "oRng.Text =" must be taken literally as
the displayed result was:
"Did he say why he crossed the road? * FORMDROPDOWN **" and not the
questions text with a functional formfield :-(
I monkey around with the oRng object a bit but I couldn't find a method
that would allow me to put the actual working content of the AutoText
entry in oRng.
Question 1 - Is there a method to put something other than literal text
in a range?
Giving up that approach, I next thought about using a find and replace
with autotext routine that me and friend Graham Mayor worked out
sometime ago.
My approach was to write a "flag" within the bookmark range then use
the find replace routine to replace the flag with the AutoText entry.
I used this code:
Sub OnExitDropDown()
Dim oFF As FormFields
Dim oRng As Word.Range
Set oFF = ActiveDocument.FormFields
Select Case
oFF("Question").DropDown.ListEntries(oFF("Question").DropDown.Value).Name
Case Is = "Yes"
ActiveDocument.Unprotect
Set oRng = ActiveDocument.Bookmarks("FUQ").Range
oRng.Text = "*@*"
ActiveDocument.Bookmarks.Add "FUQ", oRng
RWAT
ActiveDocument.Protect wdAllowOnlyFormFields, True
Case Else
ActiveDocument.Unprotect
Set oRng = ActiveDocument.Bookmarks("FUQ").Range
oRng.Text = ""
ActiveDocument.Bookmarks.Add "FUQ", oRng
ActiveDocument.Protect wdAllowOnlyFormFields, True
End Select
End Sub
And
Sub RWAT()
Dim oSPRng As Word.Range
Dim oSrchRng As Range
Dim pFN As String
'Create a scratch pad
Set oSPRng = Documents.Add.Range
NormalTemplate.AutoTextEntries("FUQ").Insert oSPRng
'Cut the inserted entry to the clipboard
oSPRng.End = ActiveDocument.Range.End - 1
oSPRng.Cut
ActiveDocument.Close wdDoNotSaveChanges
'crumple up the scratch pad
'Replace found text with the clipboard contents.
Set oSrchRng = ActiveDocument.Bookmarks("FUQ").Range
With oSrchRng.Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = "*@*"
.Replacement.Text = "^c"
.Execute Replace:=wdReplaceOne
If .Found = True Then MsgBox "Flag found" 'Added for testing
End With
End Sub
Again to my dismay and despite the Msgbox displaying "Flag found," the
result in the document at the bookmark was:
*@*
I stepped through the code repeatedly and each time all indications
where that the flag was found, the replacement executed, but the result
was the same as shown above :-(
I fiddled around with this and soon realized (but can't explain why)
that if I set the flag as "*@*" and the then searched for "*@" the
result at the bookmark was:
Did he say why he crossed the road? "a fully functional dropdown"*
Viewing this as a minor concession, I changed the flag to:
oRng.Text = "*@ " 'note the trailing space
and this left just a single extra space at the end of the bookmark
range instead of "*."
Question 2 - Can someone explain the behavior described above? Why
when the found range includes the entire bookmark range does the
replacement fail?
Thinking that I had found a solution, I set my macro to run on exit
from the "Question" formfield.
My euphoria was quickly dashed. While the code worked perfectly when I
a) stepped through it with the editor, and b) ran it directly from the
editor, it failed when triggered by tabbing out of the formfield.
It was generating a RTE 4198 "Command failed" while attempting to
execute this line of code in the RWAT procedure:
ActiveDocument.Close wdDoNotSaveChanges
Since it ran normally from the editor, I suspected that this must have
something to do with the field controlling the activedocument until the
procedure is completed. I tried all I know to create a specific
document object e.g.,
Dim oDoc as Word.Document
Set oDOC = Documents.Add
......
oDoc.Close
but I got the same error regardless of what I tried.
Question 3 - Can anyone explain the behavior described above?
Sticking with the find and replace autotext theme and convinced that
attempting to close the scratch pad was the stumbling block, I elected
to add a scratch pad at the end of the active document and then delete
it.
This is the RWAT code (note the main code stayed the same):
Sub RWAT()
Dim oSPRng As Word.Range
Dim oSrchRng As Range
'Create a note area
Set oSPRng = ActiveDocument.Range
oSPRng.Start = ActiveDocument.Range.End
'Write the AutoText entry
NormalTemplate.AutoTextEntries("FUQ").Insert oSPRng
'Cut the inserted entry to the clipboard
oSPRng.End = ActiveDocument.Range.End - 1
oSPRng.Cut
'tear off the scratch pad
'Replace flag with the clipboard contents.
Set oSrchRng = ActiveDocument.Bookmarks("FUQ").Range
With oSrchRng.Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = "*&"
.Replacement.Text = "^c"
.Execute Replace:=wdReplaceOne
End With
End Sub
This appears to be working as expected but I have not fully tested the
possible effects on the document from creating and then deleting the
note area.
Additionally, I learned that I could get rid of the extraneous space
within the bookmark by redefining the bookmark again using oRgn after
it contained the functioning AutoText and I added code to select the
new dropdown field:
Final version:
Sub RWAT()
Dim oSPRng As Word.Range
Dim oSrchRng As Range
'Create a note area
Set oSPRng = ActiveDocument.Range
oSPRng.Start = ActiveDocument.Range.End
'Write the AutoText entry
NormalTemplate.AutoTextEntries("FUQ").Insert oSPRng
'Cut the inserted entry to the clipboard
oSPRng.End = ActiveDocument.Range.End - 1
oSPRng.Cut
'tear off the scratch pad
'Replace flag with the clipboard contents.
Set oSrchRng = ActiveDocument.Bookmarks("FUQ").Range
With oSrchRng.Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = "*&"
.Replacement.Text = "^c"
.Execute Replace:=wdReplaceOne
End With
End Sub
Question 4 - This seems like a brutally complicated process yet appears
that it could be applied relatively to several scenarios.
An earlier thought this morning was to simply insert the AutoText at
the bookmark then move the bookmark range and redefined it:
This code worked but I didn't like the idea of having to "know" what
the last text character was in the formfield (i.e., the "?")
Sub OnExitDropDown1()
Dim oFF As FormFields
Dim oRng As Word.Range
Set oFF = ActiveDocument.FormFields
Select Case
oFF("DropDown1").DropDown.ListEntries(oFF("DropDown1").DropDown.Value).Name
Case Is = "To get to the other side"
ActiveDocument.Unprotect
Set oRng = ActiveDocument.Bookmarks("FUQ").Range
NormalTemplate.AutoTextEntries("FUQ").Insert oRng
oRng.MoveEndUntil Cset:="?", Count:=wdForward
oRng.MoveEnd wdWord, 2
ActiveDocument.Bookmarks.Add "FUQ", oRng
ActiveDocument.Protect wdAllowOnlyFormFields, True
ActiveDocument.Bookmarks("FUA").Range.FormFields(1).Select
Case Else
ActiveDocument.Unprotect
Set oRng = ActiveDocument.Bookmarks("FUQ").Range
oRng.Text = ""
ActiveDocument.Bookmarks.Add "FUQ", oRng
ActiveDocument.Protect wdAllowOnlyFormFields, True
End Select
End Sub
However after all this effort I am beginning to think that I should
have stayed with this idea. LOL
Interested in any other ideas and simplifications.
Thanks.
and an on exit event. My challenge (perhaps your childs play) was to
create a conditional additional question in a form.
Example:
Why did the chicken cross the road? "Dropdown field containing
multiple choices"
If the selection made above was "To get the other side" Then display a
follow-up question:
Did she say why she wanted to cross the road: "Dropdown field
containing yes and no"
I created the first question and dropdown field using "Question" as the
bookmark name.
follow-up question and dropdown field would be the easiest approach.From the beginning, I figured that using a stored AutoText entry of the
I created the follow-up question and dropdown field using "FUA" as the
bookmark name. I then stored the follow-up question and formfield as
AutoText "FUQ."
I used a bookmark "FUQ" to designate the placement of the conditional
question.
Since the FUQ needed to be displayed or hidden depending on the
condition, I realized that I would need to write either the AutoText
FUQ or "" to the bookmark range and redefine the range with each
change.
My first coding attempt was:
Sub OnExitDropDown()
Dim oFF As FormFields
Dim oRng As Word.Range
Set oFF = ActiveDocument.FormFields
Select Case
oFF("Question").DropDown.ListEntries(oFF("Question").DropDown.Value).Name
Case Is = "Yes"
ActiveDocument.Unprotect
Set oRng = ActiveDocument.Bookmarks("FUQ").Range
oRng.Text = NormalTemplate.AutoTextEntries("FUQ")
ActiveDocument.Bookmarks.Add "FUQ", oRng
ActiveDocument.Protect wdAllowOnlyFormFields, True
Case Else
ActiveDocument.Unprotect
Set oRng = ActiveDocument.Bookmarks("FUQ").Range
oRng.Text = ""
ActiveDocument.Bookmarks.Add "FUQ", oRng
ActiveDocument.Protect wdAllowOnlyFormFields, True
End Select
End Sub
To my dismay, I realized that "oRng.Text =" must be taken literally as
the displayed result was:
"Did he say why he crossed the road? * FORMDROPDOWN **" and not the
questions text with a functional formfield :-(
I monkey around with the oRng object a bit but I couldn't find a method
that would allow me to put the actual working content of the AutoText
entry in oRng.
Question 1 - Is there a method to put something other than literal text
in a range?
Giving up that approach, I next thought about using a find and replace
with autotext routine that me and friend Graham Mayor worked out
sometime ago.
My approach was to write a "flag" within the bookmark range then use
the find replace routine to replace the flag with the AutoText entry.
I used this code:
Sub OnExitDropDown()
Dim oFF As FormFields
Dim oRng As Word.Range
Set oFF = ActiveDocument.FormFields
Select Case
oFF("Question").DropDown.ListEntries(oFF("Question").DropDown.Value).Name
Case Is = "Yes"
ActiveDocument.Unprotect
Set oRng = ActiveDocument.Bookmarks("FUQ").Range
oRng.Text = "*@*"
ActiveDocument.Bookmarks.Add "FUQ", oRng
RWAT
ActiveDocument.Protect wdAllowOnlyFormFields, True
Case Else
ActiveDocument.Unprotect
Set oRng = ActiveDocument.Bookmarks("FUQ").Range
oRng.Text = ""
ActiveDocument.Bookmarks.Add "FUQ", oRng
ActiveDocument.Protect wdAllowOnlyFormFields, True
End Select
End Sub
And
Sub RWAT()
Dim oSPRng As Word.Range
Dim oSrchRng As Range
Dim pFN As String
'Create a scratch pad
Set oSPRng = Documents.Add.Range
NormalTemplate.AutoTextEntries("FUQ").Insert oSPRng
'Cut the inserted entry to the clipboard
oSPRng.End = ActiveDocument.Range.End - 1
oSPRng.Cut
ActiveDocument.Close wdDoNotSaveChanges
'crumple up the scratch pad
'Replace found text with the clipboard contents.
Set oSrchRng = ActiveDocument.Bookmarks("FUQ").Range
With oSrchRng.Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = "*@*"
.Replacement.Text = "^c"
.Execute Replace:=wdReplaceOne
If .Found = True Then MsgBox "Flag found" 'Added for testing
End With
End Sub
Again to my dismay and despite the Msgbox displaying "Flag found," the
result in the document at the bookmark was:
*@*
I stepped through the code repeatedly and each time all indications
where that the flag was found, the replacement executed, but the result
was the same as shown above :-(
I fiddled around with this and soon realized (but can't explain why)
that if I set the flag as "*@*" and the then searched for "*@" the
result at the bookmark was:
Did he say why he crossed the road? "a fully functional dropdown"*
Viewing this as a minor concession, I changed the flag to:
oRng.Text = "*@ " 'note the trailing space
and this left just a single extra space at the end of the bookmark
range instead of "*."
Question 2 - Can someone explain the behavior described above? Why
when the found range includes the entire bookmark range does the
replacement fail?
Thinking that I had found a solution, I set my macro to run on exit
from the "Question" formfield.
My euphoria was quickly dashed. While the code worked perfectly when I
a) stepped through it with the editor, and b) ran it directly from the
editor, it failed when triggered by tabbing out of the formfield.
It was generating a RTE 4198 "Command failed" while attempting to
execute this line of code in the RWAT procedure:
ActiveDocument.Close wdDoNotSaveChanges
Since it ran normally from the editor, I suspected that this must have
something to do with the field controlling the activedocument until the
procedure is completed. I tried all I know to create a specific
document object e.g.,
Dim oDoc as Word.Document
Set oDOC = Documents.Add
......
oDoc.Close
but I got the same error regardless of what I tried.
Question 3 - Can anyone explain the behavior described above?
Sticking with the find and replace autotext theme and convinced that
attempting to close the scratch pad was the stumbling block, I elected
to add a scratch pad at the end of the active document and then delete
it.
This is the RWAT code (note the main code stayed the same):
Sub RWAT()
Dim oSPRng As Word.Range
Dim oSrchRng As Range
'Create a note area
Set oSPRng = ActiveDocument.Range
oSPRng.Start = ActiveDocument.Range.End
'Write the AutoText entry
NormalTemplate.AutoTextEntries("FUQ").Insert oSPRng
'Cut the inserted entry to the clipboard
oSPRng.End = ActiveDocument.Range.End - 1
oSPRng.Cut
'tear off the scratch pad
'Replace flag with the clipboard contents.
Set oSrchRng = ActiveDocument.Bookmarks("FUQ").Range
With oSrchRng.Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = "*&"
.Replacement.Text = "^c"
.Execute Replace:=wdReplaceOne
End With
End Sub
This appears to be working as expected but I have not fully tested the
possible effects on the document from creating and then deleting the
note area.
Additionally, I learned that I could get rid of the extraneous space
within the bookmark by redefining the bookmark again using oRgn after
it contained the functioning AutoText and I added code to select the
new dropdown field:
Final version:
Sub RWAT()
Dim oSPRng As Word.Range
Dim oSrchRng As Range
'Create a note area
Set oSPRng = ActiveDocument.Range
oSPRng.Start = ActiveDocument.Range.End
'Write the AutoText entry
NormalTemplate.AutoTextEntries("FUQ").Insert oSPRng
'Cut the inserted entry to the clipboard
oSPRng.End = ActiveDocument.Range.End - 1
oSPRng.Cut
'tear off the scratch pad
'Replace flag with the clipboard contents.
Set oSrchRng = ActiveDocument.Bookmarks("FUQ").Range
With oSrchRng.Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = "*&"
.Replacement.Text = "^c"
.Execute Replace:=wdReplaceOne
End With
End Sub
Question 4 - This seems like a brutally complicated process yet appears
that it could be applied relatively to several scenarios.
An earlier thought this morning was to simply insert the AutoText at
the bookmark then move the bookmark range and redefined it:
This code worked but I didn't like the idea of having to "know" what
the last text character was in the formfield (i.e., the "?")
Sub OnExitDropDown1()
Dim oFF As FormFields
Dim oRng As Word.Range
Set oFF = ActiveDocument.FormFields
Select Case
oFF("DropDown1").DropDown.ListEntries(oFF("DropDown1").DropDown.Value).Name
Case Is = "To get to the other side"
ActiveDocument.Unprotect
Set oRng = ActiveDocument.Bookmarks("FUQ").Range
NormalTemplate.AutoTextEntries("FUQ").Insert oRng
oRng.MoveEndUntil Cset:="?", Count:=wdForward
oRng.MoveEnd wdWord, 2
ActiveDocument.Bookmarks.Add "FUQ", oRng
ActiveDocument.Protect wdAllowOnlyFormFields, True
ActiveDocument.Bookmarks("FUA").Range.FormFields(1).Select
Case Else
ActiveDocument.Unprotect
Set oRng = ActiveDocument.Bookmarks("FUQ").Range
oRng.Text = ""
ActiveDocument.Bookmarks.Add "FUQ", oRng
ActiveDocument.Protect wdAllowOnlyFormFields, True
End Select
End Sub
However after all this effort I am beginning to think that I should
have stayed with this idea. LOL
Interested in any other ideas and simplifications.
Thanks.