Unexpected results when replacing text using TextRange.Replace - help!

  • Thread starter david.f.jenkins
  • Start date
D

david.f.jenkins

I'm hoping I can get a) an explanation for the results I'm seeing, and
b) some guidance on how to achieve the results I want.

I've written the following macro:

Option Explicit

Sub Replace_Test()

Dim NewRange, TempRange As TextRange
Dim myDocument

Set myDocument = ActivePresentation.Slides(1)
With myDocument.Shapes.AddShape(msoShapeRectangle, 0, 0, 250,
140).TextFrame
.TextRange.Text = "abcd efgh"
.MarginLeft = 10
.MarginRight = 10

Set NewRange = .TextRange.Characters(.TextRange.Start, 4)
Set TempRange = NewRange.replace(FindWhat:="abcd", _
Replacewhat:="wxyz", _
WholeWords:=msoFalse, _
MatchCase:=msoFalse)

End With
End Sub

When debugging, NewRange.Text contains "abcd" before the replace, but
"wxyz efgh" after the replace; TempRange shows the expected "wxyz"
after the replace. Why has the NewRange text been expanded to include
the " efgh"? What I'm expecting (and what I need) is for NewRange to
contain "wxyz" after the replace.

I imagine that I'm exhibiting my ignorance in the proper use of
references, objects, etc., but I'm out of ideas as to what to try next.
Hope you all can clear this up for me - it's caused untold grief over
the last day or so!
 
D

David M. Marcovitz

Here is what I believe is happening, but I'm not sure. You create a
shape, and it contains a TextRange object. You set NewRange to point to
the beginning of that TextRange Object. However, this does not create a
new object that just contains the beginning characters. It is actually a
pointer to the old TextRange object with an indication that it only
contains 4 characters. This is a good thing because when you change
NewRange, the text in the text box really changes.

I'm guessing that Replace is mucking up the length of NewRange so when
you replace the characters, NewRange no longer knows how long it is
supposed to be so it just becomes the entire range once again.

--David

--
David M. Marcovitz
Microsoft PowerPoint MVP
Director of Graduate Programs in Educational Technology
Loyola College in Maryland
Author of _Powerful PowerPoint for Educators_
http://www.loyola.edu/education/PowerfulPowerPoint/

(e-mail address removed) wrote in @o13g2000cwo.googlegroups.com:
 
D

david.f.jenkins

Thanks, David. I believe you're right, but I've put below a version of
the test that's a little closer to what's acraully going on. In real
life, I'm attempting to do the replace on selected text from the
screen:

Option Explicit

Sub Replace_Test()

Dim TempRange As TextRange
Dim myDocument
Dim TestRange As TextRange

Set myDocument = ActivePresentation.Slides(1)
With myDocument.Shapes.AddShape(msoShapeRectangle, 0, 0, 250,
140).TextFrame
.TextRange.Text = "abcd efgh"
.MarginLeft = 10
.MarginRight = 10

..TextRange.Characters(1, 4).Select

With ActiveWindow.Selection
Set TestRange = .TextRange
End With

Set TempRange = TestRange.replace(FindWhat:="abcd", _
Replacewhat:="wxyz", _
WholeWords:=msoFalse, _
MatchCase:=msoFalse)

End With
End Sub


In this case, the "abcd" shows as selected on the screen, but when
debugging TestRange after the replace, it again shows the "wxyz efgh".
Since all I'm operating on is the selected text, how in the world did
he ever take it upon himself to look at the rest of the text in the
affected shape? Do you suppose it's because he knows that he may have
to shove some words around to accomodate the replace, and hence feels
it's his preogative to modify the textrange text with the text
appearing in the shape that's to the right of the replaced text?

Not too sure I'm happy with the way he's doing that. What do you
think?
 
D

David M. Marcovitz

Yes, but even though you are using selections, you are still using a
TextRange, so it doesn't matter that the TextRange is based on your
selection. It is still pointing to the original TextRange.

So, other than being annoyed that Replace changes your limited TextRange
back to the complete original TextRange, is there a problem? If this is
causing problems, you might want to work with Strings, rather than TextRanges
and use the Replace Function, rather than the Replace method of TextRange.
When the Replace funtion returns a string, it's not a pointer to anything;
it's a real live new string.

--David

David Marcovitz
Microsoft PowerPoint MVP
Author of _Powerful PowerPoint for Educators_
http://www.loyola.edu/education/PowerfulPowerPoint/
 
D

david.f.jenkins

Well, my original TextRange was the selected text:
ActiveWindow.Selection.TextRange, and it contained only "abcd", didn't
it, not "abcd efgh"?

I thought that would create a TextRange object for only the selected
text, and as a mater of fact, that's what it appeared to do until I
executed the .Replace. Once I've done that, he now seems to deal with
all of the text in the shape that contains all the text.

The reason that causes me gief is that I only want to do all of my
operations on the string of text the user has selected. If that string
gets expanded in the middle of my operations, then I'm up the creek (as
has been happening).

I've got a semi-workaround that I'm testing, and that is to set
TestRange = ActiveWindow.Selection.TextRange after each replace - this
seems to be working, but it's really only a workaround.
 
D

david.f.jenkins

I've been dealing with the textrange methods, because the selected text
I'm working on will have variable formatting. If I use just the normal
text modification operations, it appears to pick up the formatting from
the first character of the replaced text. Not too sure about that, but
formatting is certainly screwed up. When I use the TextRange
manipulation operations, it appears that those methods try (as best as
possible) to maintain original formatting for replaced text, etc.

Am I missing something simple here?
 
D

david.f.jenkins

No, I'm not always replacing character-by-character. As a matter of
fact, I'm using regexes to find the text to modify, and the replacement
usually incorporates part of the found text, so I have to jump though
hoops to find out what the regex matched, then do a replace of that in
the source string with what the regex created for replacement text. A
real pain in the neck...

I've thought of the character-by-character process, but don't believe
that it will buy me much.

My biggest problem now is the following: suppose I have "abc def",
where "abc" is italicised, and "def" is not. If I have to modify
"def", it ends up getting italicised. I'm really doing a replace of "
def ", and when I do the replace, I believe the leading blank somehow
is carrying along formatting info picked up from the preceding "abc".
I have modified the code to ignore the preceding blank(s) when doing
the replace (now I have to do find (for " def " and THEN a replace (of
"def ")) and it appears to leave the formatting of "def" as it was.

Thanks again for you explanations and help...
 
Top