Hi,

I want to be able to parse the contents of a document, and possibly
change a single word in the text. Unfortunately inserting textboxes
seem to have strange effects on the document.

If I have a document that has this content:

"Hello world"

I get this:

ActiveDocument.Range.Text is "Hello world"

ActiveDocument.Range(7, 12).Text is "world"

However, if I add a Text box in front of "Hello world", so the
document looks like this:

---
BOX
Goodbye world
BOX_END
Hello world
---

I get this:

ActiveDocument.Range.Text is "\x01\x15Hello world"

ActiveDocument.Range(7, 12).Text is " \\* "

ActiveDocument.Range(9, 14).Text is "\\* ME"

What gives?

Sincerely,
Anders S. Johansen

Re: Textboxes and their influence on the behaviour of ranges by fumei

fumei
Fri Jan 18 11:44:13 PST 2008

If you expanded your Start and End of your range, you would see

"\\* MEREGEFORMAT

When using Range.Text you are picking up the field code text of the textbox.

In your document, press Alt-F9. This will toggle field codes. You should
see something like:

{ SHAPE \* MERGEFORMAT }Hello World

Range.Text is operating literally. And literally, the textbox is made up of
a field code, which is, literally, text.


anders.johansen@gmail.com wrote:
>Hi,
>
>I want to be able to parse the contents of a document, and possibly
>change a single word in the text. Unfortunately inserting textboxes
>seem to have strange effects on the document.
>
>If I have a document that has this content:
>
>"Hello world"
>
>I get this:
>
>ActiveDocument.Range.Text is "Hello world"
>
>ActiveDocument.Range(7, 12).Text is "world"
>
>However, if I add a Text box in front of "Hello world", so the
>document looks like this:
>
>---
>BOX
>Goodbye world
>BOX_END
>Hello world
>---
>
>I get this:
>
>ActiveDocument.Range.Text is "\x01\x15Hello world"
>
>ActiveDocument.Range(7, 12).Text is " \\* "
>
>ActiveDocument.Range(9, 14).Text is "\\* ME"
>
>What gives?
>
>Sincerely,
> Anders S. Johansen

--
Message posted via OfficeKB.com
http://www.officekb.com/Uwe/Forums.aspx/word-programming/200801/1


Re: Textboxes and their influence on the behaviour of ranges by anders

anders
Fri Jan 18 13:02:42 PST 2008

On Jan 18, 8:44=A0pm, "fumei via OfficeKB.com" <u37563@uwe> wrote:
> When using Range.Text you are picking up the field code text of the textbo=
x.

All right.

So I guess I am not using the right approach here. Is there another
one? The only alternative I have come up with is manipuating
Selection, and moving it first to the start of the document, then
moving the start and the end in units of characters... which works,
but is slow in large documents...

Parsing any field seems nigh-on impossible.

Anders

Re: Textboxes and their influence on the behaviour of ranges by Tony

Tony
Fri Jan 18 16:05:48 PST 2008

The Range Method returns a Range Object. If you qualify the method with
start and end positions they relate to the underlying structure of the
document; if you don't you get the whole document (including hidden
controls) as though you had specified the start and end of the whole
document.

When you use the Text Property of a Range object you get a string which is
just the 'visible' content of that range (you can control what 'visible'
means - see the TextRetrievalMode if interested - but the default is what
you see on screen). If you want, you can take a substring of the Text
property to get what it seems you are looking for.

So ...

... in your example with the textbox ...

Range(9,14) picks up characters 9 through 14 of the underlying document
including invisible controls (" \* ME") as you saw

Range.text picks up the visible part of the document (the shape placeholder,
a control delimiter, then your text). The substring Mid(range.text,9,6) will
pick up characters 9 through 14 of that visible text ("world" followed by a
paragraph mark) .

--
Enjoy,
Tony

<anders.johansen@gmail.com> wrote in message
news:63ec6e8f-8b18-4160-8c75-9ffa81d5b7b2@v29g2000hsf.googlegroups.com...
On Jan 18, 8:44 pm, "fumei via OfficeKB.com" <u37563@uwe> wrote:
> When using Range.Text you are picking up the field code text of the
> textbox.

All right.

So I guess I am not using the right approach here. Is there another
one? The only alternative I have come up with is manipuating
Selection, and moving it first to the start of the document, then
moving the start and the end in units of characters... which works,
but is slow in large documents...

Parsing any field seems nigh-on impossible.

Anders


Re: Textboxes and their influence on the behaviour of ranges by anders

anders
Fri Jan 18 22:27:17 PST 2008

On Jan 19, 1:05=A0am, "Tony Jollans" <My forename at my surname dot com>
wrote:
> The Range Method returns a Range Object. If you qualify the method with
> start and end positions they relate to the underlying structure of the
> document; if you don't you get the whole document (including hidden
> controls) as though you had specified the start and end of the whole
> document.
>
> When you use the Text Property of a Range object you get a string which is=

> just the 'visible' content of that range (you can control what 'visible'
> means - see the TextRetrievalMode if interested - but the default is what
> you see on screen). If you want, you can take a substring of the Text
> property to get what it seems you are looking for.

OK. That makes more sense.

Unfortunately, what I want to do is:

1) Get the visible text
2) Parse it
3) Possibly create a Range that covers a part of the visible text
based on the parsing I did.

I.e., I would love to be able to create a Range, based on positions in
the visible text, but what you are telling me is that that is not
possible, right?

Anders

Re: Textboxes and their influence on the behaviour of ranges by Tony

Tony
Sat Jan 19 02:52:42 PST 2008

It depends on what you want to do with the Range.

Generally speaking, when working with the document, behind the scenes as it
were, you have to be aware of the whole document. However, using default
settings, your code can, by and large, mimic the behaviour you would see on
screen.

A Range has a Characters Collection, and each Character is, itself, a Range
object. You could use this collection to define the range you want by
picking the start of the range of the first character and the end of the
range of the last character, but be careful ...

... in your example \x01\x15 is a single Character (Range) object, and thus

ActiveDocument.Range( _
ActiveDocument.Range.Characters(8).Start, _
ActiveDocument.Range.Characters(12).End)

(deliberately spread over three lines to stop the newsreader breaking it
inappropriately)

... will return the Range containing the visible "world".

--
Enjoy,
Tony

<anders.johansen@gmail.com> wrote in message
news:ccd2155f-9dcf-4ff6-abc9-8896bea383fc@e4g2000hsg.googlegroups.com...
On Jan 19, 1:05 am, "Tony Jollans" <My forename at my surname dot com>
wrote:
> The Range Method returns a Range Object. If you qualify the method with
> start and end positions they relate to the underlying structure of the
> document; if you don't you get the whole document (including hidden
> controls) as though you had specified the start and end of the whole
> document.
>
> When you use the Text Property of a Range object you get a string which is
> just the 'visible' content of that range (you can control what 'visible'
> means - see the TextRetrievalMode if interested - but the default is what
> you see on screen). If you want, you can take a substring of the Text
> property to get what it seems you are looking for.

OK. That makes more sense.

Unfortunately, what I want to do is:

1) Get the visible text
2) Parse it
3) Possibly create a Range that covers a part of the visible text
based on the parsing I did.

I.e., I would love to be able to create a Range, based on positions in
the visible text, but what you are telling me is that that is not
possible, right?

Anders


Re: Textboxes and their influence on the behaviour of ranges by anders

anders
Sun Jan 20 12:35:05 PST 2008

On Jan 19, 11:52=A0am, "Tony Jollans" <My forename at my surname dot
com> wrote:
> =A0... in your example \x01\x15 is a single Character (Range) object, and =
thus
>
> ActiveDocument.Range( _
> =A0 =A0 =A0 =A0 ActiveDocument.Range.Characters(8).Start, _
> =A0 =A0 =A0 =A0 ActiveDocument.Range.Characters(12).End)
>
> (deliberately spread over three lines to stop the newsreader breaking it
> inappropriately)
>
> =A0... will return the Range containing the visible "world".

All right, that works pretty much the way I wanted, and having banged
it sufficiently over its head, it now works exacly as it should...
Thank you very much for your help!

Now I have another problem.

Say I have a document that looks like this:

------------------
TEXT BOX BEGINS
Hello world
TEXT BOX ENDS
Goodbye world
------------------

=2E..and my cursor is in the text box ("Hello world").

When using Application.ActiveDocument.Characters, I get the Characters
in the "actual" document, e.g. "Goodbye world".

This also happens if instead of ActiveDocument, I use
Selection.Document.

What do I do, if instead I want to get the Characters range that the
cursor is currently on, e.g. "Hello world" if the cursor is in the
text box, and "Goodbye world" if it is not?

Anders

Re: Textboxes and their influence on the behaviour of ranges by Tony

Tony
Mon Jan 21 03:39:48 PST 2008

On the plus side, you're making progress :)

Document content is held in several parts, called Stories, which come
together to produce the display (or print). What you have been working with
so far (Activedocument.Range) is the Main Text Story and within that you
have seen a placeholder for your textbox (\x01, more generally a placeholder
for a graphic). The test inside the Textbox is held as a TextRange within a
TextFrame within the Textbox Shape. It is also part of the document's
TextFrame Story (which is actually a series of stories, one per Textbox or,
strictly, one per chain of textboxes - if you have linked ones).

You can access the series of TextFrame Stories from the selection by
starting with ...

Set MyRange = ActiveDocument.StoryRanges(Selection.StoryType)

... and then iterating over them with ...

Set MyRange = MyRange.NextStoryRange

... but this is probably not the best way for you - although it does work
whether in a Textbox or the Main Text - or any other story.

What is probably better is to identify, first of all, that your Selection is
in a Textbox (Selection.StoryType = wdTextFrameStory) and then look at
Selection.ShapeRange.TextFrame.TextRange, which is a Range just like
Application.Range (and can, itself contain nested textboxes, etc.). You can
process the Characters in this Range in the same way you processed those in
the main document.

--
Enjoy,
Tony

<anders.johansen@gmail.com> wrote in message
news:490dcb53-f2ab-40b4-afde-ac503d48b3a0@d70g2000hsb.googlegroups.com...
On Jan 19, 11:52 am, "Tony Jollans" <My forename at my surname dot
com> wrote:
> ... in your example \x01\x15 is a single Character (Range) object, and
> thus
>
> ActiveDocument.Range( _
> ActiveDocument.Range.Characters(8).Start, _
> ActiveDocument.Range.Characters(12).End)
>
> (deliberately spread over three lines to stop the newsreader breaking it
> inappropriately)
>
> ... will return the Range containing the visible "world".

All right, that works pretty much the way I wanted, and having banged
it sufficiently over its head, it now works exacly as it should...
Thank you very much for your help!

Now I have another problem.

Say I have a document that looks like this:

------------------
TEXT BOX BEGINS
Hello world
TEXT BOX ENDS
Goodbye world
------------------

...and my cursor is in the text box ("Hello world").

When using Application.ActiveDocument.Characters, I get the Characters
in the "actual" document, e.g. "Goodbye world".

This also happens if instead of ActiveDocument, I use
Selection.Document.

What do I do, if instead I want to get the Characters range that the
cursor is currently on, e.g. "Hello world" if the cursor is in the
text box, and "Goodbye world" if it is not?

Anders


Re: Textboxes and their influence on the behaviour of ranges by anders

anders
Thu Jan 24 10:57:52 PST 2008

On Jan 21, 12:39=A0pm, "Tony Jollans" <My forename at my surname dot
com> wrote:
> On the plus side, you're making progress :)

Yup! Also with going nuts ;)

> What is probably better is to identify, first of all, that your Selection =
is
> in a Textbox (Selection.StoryType =3D wdTextFrameStory) and then look at
> Selection.ShapeRange.TextFrame.TextRange, which is a Range just like
> Application.Range (and can, itself contain nested textboxes, etc.). You ca=
n
> process the Characters in this Range in the same way you processed those i=
n
> the main document.

All right.

I am still having problems getting the TextRange from TextFrame. I am
not using Word - I am accessing Word from Borland C++ Builder - but
everything else works fine.

When (if) I can reliably get the Characters from a TextBox, I just
need a way to create a new range from the start and end characters,
when dealing with a text box. I apparently can't use the
ActiveDocument, as it is not the host of the Characters collection in
question, but none of the parent objects.

Thank you for your help so far!

Anders

Re: Textboxes and their influence on the behaviour of ranges by Tony

Tony
Fri Jan 25 03:13:53 PST 2008

Alright! This is not entirely straightforward. There is no immediate route
to the Range of the textbox you are in but this will do it:

Dim MyRange As Range, MyChar As Range
If Selection.StoryType = wdTextFrameStory Then
Set MyRange = ActiveDocument.StoryRanges(wdTextFrameStory)
While Not Selection.InRange(MyRange)
Set MyRange = MyRange.NextStoryRange
Wend
EndIf


MyRange is now a Range like any other. It is a Range Object and there is no
parent with a Range Property that takes start and end parameters. When you
determine (through its Characters collection) the start and end you need you
must then explicitly set them - or maybe if you want to keep the original
you can do this ..

Dim MyNewrange as Range
Set MyNewRange = MyRange.Duplicate
MyNewRange.Start = MyRange.Characters(7).Start ' perhaps
MyNewRange.End = MyRange.Characters(15).End ' perhaps



--
Enjoy,
Tony

<anders.johansen@gmail.com> wrote in message
news:b01c521f-5397-4718-9de8-0d52b6f17f22@n20g2000hsh.googlegroups.com...
On Jan 21, 12:39 pm, "Tony Jollans" <My forename at my surname dot
com> wrote:
> On the plus side, you're making progress :)

Yup! Also with going nuts ;)

> What is probably better is to identify, first of all, that your Selection
> is
> in a Textbox (Selection.StoryType = wdTextFrameStory) and then look at
> Selection.ShapeRange.TextFrame.TextRange, which is a Range just like
> Application.Range (and can, itself contain nested textboxes, etc.). You
> can
> process the Characters in this Range in the same way you processed those
> in
> the main document.

All right.

I am still having problems getting the TextRange from TextFrame. I am
not using Word - I am accessing Word from Borland C++ Builder - but
everything else works fine.

When (if) I can reliably get the Characters from a TextBox, I just
need a way to create a new range from the start and end characters,
when dealing with a text box. I apparently can't use the
ActiveDocument, as it is not the host of the Characters collection in
question, but none of the parent objects.

Thank you for your help so far!

Anders


Re: Textboxes and their influence on the behaviour of ranges by anders

anders
Sun Jan 27 04:31:57 PST 2008

On 25 Jan., 12:13, "Tony Jollans" <My forename at my surname dot com>
wrote:
> Alright! This is not entirely straightforward. There is no immediate route
> to the Range of the textbox you are in but this will do it:

<...>

All right! This works very well for me! Thank you ever so much for the
help and insights you have provided.

Sincerely,
Anders

Re: Textboxes and their influence on the behaviour of ranges by Tony

Tony
Sun Jan 27 05:14:55 PST 2008

My pleasure!

--
Enjoy,
Tony

<anders.johansen@gmail.com> wrote in message
news:d9679f96-aae4-42d7-abf8-1e3b51522d8d@e10g2000prf.googlegroups.com...
> On 25 Jan., 12:13, "Tony Jollans" <My forename at my surname dot com>
> wrote:
>> Alright! This is not entirely straightforward. There is no immediate
>> route
>> to the Range of the textbox you are in but this will do it:
>
> <...>
>
> All right! This works very well for me! Thank you ever so much for the
> help and insights you have provided.
>
> Sincerely,
> Anders