The "Invalid use of property" error appears because Range.Start and Range.End are value properties, not objects, so they cannot be assigned with Set. You can only use Set on object references; for a property like .Start, a plain assignment (or better, building the range in one call) is the right approach. Once you correct that, there is a second pitfall waiting: bookmarks used as insertion markers tend to drift or get destroyed when you replace the text between them, so your macro must re-anchor them after each write.
Why the Error Occurs
In VBA, Set exists exclusively to assign object references. When you write:
Set myRange.Start = ActiveDocument.Bookmarks("SaveDateStart").Range.End
the compiler sees Set applied to .Start, which is a Long property, and reports "Invalid use of property." The .End part of the bookmark expression returns a character position number, not an object, so there is nothing for Set to assign. Removing Set makes the line compile, but it still leaves you assigning positions one at a time to an uninitialized range — which is fragile and harder to read.
The Reliable Pattern: Build the Range in One Call
Rather than mutating a range's endpoints, store the two bookmark positions in variables and construct the range directly from the document:
Sub FileSave()
Dim startPos As Long
Dim endPos As Long
startPos = ActiveDocument.Bookmarks("SaveDateStart").Range.End
endPos = ActiveDocument.Bookmarks("SaveDateEnd").Range.Start
ActiveDocument.Range(Start:=startPos, End:=endPos).Text = "Lorem Ipsum"
ActiveDocument.Save
End Sub
This reads the start position (the end of the opening bookmark), the end position (the start of the closing bookmark), and creates a fresh range spanning exactly the area between them. Assigning the .Text property replaces whatever sits in that span. Note that a named-argument call like ActiveDocument.Range(Start:=startPos, End:=endPos) is clearer than passing positional arguments, and it avoids the compiler confusion that mixing Set and property access can cause.
Reading Values from Object Properties
A frequent source of confusion is that the same expression needs different treatment depending on which side of the assignment it sits. Reading a property through an object — for example ActiveDocument.Bookmarks("SaveDateStart").Range.End — requires no Set and yields a plain number. Assigning an object, such as Set myRange = ActiveDocument.Range(1, 5), does require Set. A quick rule of thumb:
Setonly when the right-hand side returns an object (aRange,Bookmark,Document, etc.).- Plain assignment for anything returning a value:
.Start,.End,.Text,.Count.
Why the Text Duplicates on Subsequent Saves
Even after fixing the syntax, the macro may behave incorrectly the second time it runs. If your two bookmarks were inserted as empty markers (nothing selected when they were added), Word keeps the closing bookmark immediately in front of any text that appears between the markers. When your macro replaces the range with new text, the closing bookmark ends up before the text rather than after it. On the next save, the span between the two bookmarks is empty, so the macro inserts the string again instead of replacing the old one — the document accumulates a growing pile of repeated text before the old copy.
Re-Anchor the Closing Bookmark After Each Write
The fix is to move the closing bookmark to the position right after the new text each time the macro runs:
Sub FileSave()
Dim startPos As Long
Dim newText As String
newText = "Lorem Ipsum"
startPos = ActiveDocument.Bookmarks("SaveDateStart").Range.End
ActiveDocument.Range(Start:=startPos, _
End:=ActiveDocument.Bookmarks("SaveDateEnd").Range.Start).Text = newText
' Recreate SaveDateEnd immediately after the new text
ActiveDocument.Bookmarks.Add Name:="SaveDateEnd", _
Range:=ActiveDocument.Range(startPos + Len(newText), startPos + Len(newText))
ActiveDocument.Save
End Sub
Calling Bookmarks.Add with an existing name silently replaces the old bookmark, so the closing marker always sits at the end of the inserted content. An alternative design is to use a single bookmark wrapping the whole replaceable region: capture its .Range, set the text, then re-add the bookmark over the modified range. Both approaches achieve the same result; the two-marker version suits documents where other content lives between the markers is deliberately excluded, while the single-bookmark version is simpler when the entire span is yours to replace.
Prevention Tips
- Store character positions in
Longvariables before doing any work; document edits during the macro can shift positions and invalidate stale range objects. - Never rely on
Setfor value properties — the compiler error is your friend here, since it catches the mistake before runtime. - After writing text, always verify that any bookmarks used as markers still bracket the intended content, and re-add them if necessary.
- Test the macro by saving the document three or four times in a row; duplication bugs caused by bookmark drift only appear on the second run.
Frequently Asked Questions
Can I assign Range.Start directly without Set?
Yes, but only after the range exists. myRange.Start = 10 compiles fine once myRange has been initialized with Set myRange = .... The error occurs only when Set is used on the property itself, or when the range variable is Nothing.
Why does my macro insert the text twice instead of replacing it?
Most likely the closing bookmark has drifted to the front of the inserted text, leaving an empty span between the bookmarks. Re-add the closing bookmark at startPos + Len(newText) after each write.
Does Bookmarks.Add overwrite an existing bookmark with the same name?
Yes. Calling ActiveDocument.Bookmarks.Add with a name that already exists replaces the old bookmark, which is exactly what you want when repositioning a marker.
What does Range.End actually return for a bookmark?
It returns a Long character position — the offset just past the last character of the bookmark's range. For an empty (collapsed) bookmark, .Start and .End are equal.
Is there a way to insert text at a bookmark without deleting it?
Yes. Assign to the bookmark's range text and then re-add the bookmark over the new content, or collapse the range to the bookmark's start before inserting. The re-add approach shown above is the most robust for repeated updates.