Suppose I want to add some text at the end of a document and immediately access
it as a Range
object so I can set some properties of it without affecting the preceding text. Ideally, the Range.InsertAfter
method would return a Range object which would be perfect for this, but it doesn't.
It irks me that Word must know perfectly well what range defines the result of calling InsertAfter
, but on the face of it, I need to calculate it "after the fact" from the length of the inserted text, or in some other way.
So I've devised a simple-minded work-around. In pseudo-code (actually it's Delphi code but I hope that won't discourage VBA answers) what I do is this
ARange := Document.Range
ARange.Text := 'AAA'
AEnd := ARange.End - 1 // AEnd is an integer
ARange.SetRange(AEnd, AEnd)
ARange.Text := 'XXX'
ARange.Bold := True
and it seems that I can carry on indefinitely adding blocks of text to the end of a document by repeating the second block of code.
The line
ARange.SetRange(AEnd, AEnd)
as I understand it, seems to construct a new Range at the end of the existing one (unlike calling Collapse on an existing range), and works fine for the simple test cases I've tried. But it leaves me wondering whether I'm missing a trick somewhere. Is there a more direct way to append a range to a document and get a reference to it?
PS: I should have been a bit clearer that I'm trying to do this without using the Selection object (for a variety of reasons, including the fact that you can only have one of them at at time).
There are various ways to get the Range at the end of the document. You've discovered one, but as you say, it's somewhat circuitous. My preference:
Word.Range rngEndOfDoc = Document.Content;
//Content returns a Range object and is a property, not a method like Range()
rngEndOfDoc.Collapse(Word.WdCollapseDirection.wdCollapseEnd);
rngEndOfDoc.Text = "Text at the end of the document";
Collapsing the Range is conceptually like pressing the Right (or Left) arrow key when you have a selection. So rngEndOfDoc becomes a "point" rather than containing the entire content of the main body of the document.
FWIW I can never think of a situation when I'd use EndKey for this (emulate user actions) and I'd only change the Selection when I want to leave the user at the end of the document so that he can start typing at that location.
With thanks for the three admirable answers from others, I thought I would add my own. The following are two versions of the function that I started out wishing Word provided natively, returning an appended range.
The first version uses the MS Word objects in the MS Word Type Library import unit that traditionally comes with Delphi (e.g. the Word2000.Pas one), and uses "early binding" automation, while the second version does the same thing using late binding.
function AppendRange(InputRange : Range) : Range;
var
Direction : OleVariant;
begin
Result := InputRange;
Direction := wdCollapseEnd;
Result.Collapse(Direction);
end;
function AppendRangeLB(InputRange : OleVariant) : OleVariant;
begin
Result := InputRange;
Result.Collapse(wdCollapseEnd);
end;
Usage is e.g.
AppendedRange := AppendRange(ExistingRange);
AppendedRange.Text := 'YYY';
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With