IntelliSense & Passing Range and/or Document Objects

S

StevenM

I realize that my questions here might be simply a matter of taste and
programming style, but I’m also wanting to run this pass those on this forum
to make sure I’m not getting myself into trouble by making unwarranted
assumptions.

I’ve been using the following to open a new document and to set a range
object.
Dim oDoc as Document
Dim oRange as Range
Set oDoc = Documents.Add(sTemplate)
Set oRange = Selection.Range

But, if I’m not mistaken, this is the same as:

Set oDoc = Documents.Add(sTemplate)
Set oRange = oDoc.Range

Yes? Is there a difference between them? (And doesn’t the latter make more
sense? At least it took me some time to figure out that by creating a new
document, the new document as now the active document, and so here
“Selection†= “oDoc,†yes?)

Also, I’ve been passing both the document object and range object to
functions, would it be simpler to pass only the range object and when/if I
need the document object to recreate it such as:

Function Xyz(ByVal oRange as Range, ... etc.)
Dim oDoc as Document

Set oDoc = oRange.Parent

It also seems to me that:
Dim oStyle as Style

Set oStyle = oDoc.Styles("Some Styleâ€)

is the same thing as:

Set oStyle = oRange.Parent.Styles("Some Sytle")

Both statements appear to work equally well, the only difference appears to
be that the IntelliSense doesn’t work with “oRange.Parent,†but the code ran
fine.

It also seems to me that one could even dispense with creating a styles
object and write:

Dim ptFontSize as Single
ptFontSize = oRange.Parent.Styles(“Some Styleâ€).Font.Size

I apologize if all this seem trivial, but it has taken me hours to figure
all this out. My question is this: Instead of passing both a document object
and its range object to another function, wouldn’t it simplify things to pass
only one, and then use that object to create the other if needed? The reason
I ask is that my current project works with three documents, and passing
three ranges, plus one or two document objects, as well as other variables.
It creates a long and cumbersome augment/parameter list. Or am I better off
with a long augment/parameter list?

I would greatly appreciate any feedback on the above.

Steven Craig Miller
 
J

Jean-Guy Marcil

StevenM said:
I realize that my questions here might be simply a matter of taste and
programming style, but I’m also wanting to run this pass those on this forum
to make sure I’m not getting myself into trouble by making unwarranted
assumptions.

I’ve been using the following to open a new document and to set a range
object.
Dim oDoc as Document
Dim oRange as Range
Set oDoc = Documents.Add(sTemplate)
Set oRange = Selection.Range

But, if I’m not mistaken, this is the same as:

Set oDoc = Documents.Add(sTemplate)
Set oRange = oDoc.Range

Yes? Is there a difference between them? (And doesn’t the latter make more
sense? At least it took me some time to figure out that by creating a new
document, the new document as now the active document, and so here
“Selection†= “oDoc,†yes?)

The latter is safer, especially when handling more than one document. If you
always use the Selection object, it will eventually mess things up because
the selection will not be what you think it is. You never have this problem
with a Range object.

Also, your two statements are different:
Set oRange = Selection.Range
is equal to "", because the Selection is the insertion point.
Whereas
Set oRange = oDoc.Range
is equal to "¶", which is the total range of the oDoc object.
Also, I’ve been passing both the document object and range object to
functions, would it be simpler to pass only the range object and when/if I
need the document object to recreate it such as:

Function Xyz(ByVal oRange as Range, ... etc.)
Dim oDoc as Document

Set oDoc = oRange.Parent

It also seems to me that:
Dim oStyle as Style

Set oStyle = oDoc.Styles("Some Styleâ€)

is the same thing as:

Set oStyle = oRange.Parent.Styles("Some Sytle")

Both statements appear to work equally well, the only difference appears to
be that the IntelliSense doesn’t work with “oRange.Parent,†but the code ran
fine.

Because ".Parent" can be anything, Intellisense never offers anything when
you use it (It does not try to determine what the Parent is).
If you need help, what you can do is create a dummy object, in this case a
dummy document object. Then use Intellisense on that dummy object until you
get what you need. When you have found the syntax you want, just copy/paste
from the dummy object to the ".Parent" one before deleting the dummy object.
It also seems to me that one could even dispense with creating a styles
object and write:

Dim ptFontSize as Single
ptFontSize = oRange.Parent.Styles(“Some Styleâ€).Font.Size

If all you need is a style font size, then, yes, you do not need to create
the object. But if you access many properties, and modify them, then creating
the object makes sense.
I apologize if all this seem trivial, but it has taken me hours to figure
all this out. My question is this: Instead of passing both a document object
and its range object to another function, wouldn’t it simplify things to pass
only one, and then use that object to create the other if needed? The reason
I ask is that my current project works with three documents, and passing
three ranges, plus one or two document objects, as well as other variables.
It creates a long and cumbersome augment/parameter list. Or am I better off
with a long augment/parameter list?

I guess it depends what you are comfortable with.

If you make extensive use of an object, then I guess it make sense to pass
it along, so that when you see the Function, you are reminded of the objects
it works on. Also, it depends if you modify those objects or not. If you do,
you may want to use ByRef so that whatever modifications the Function make,
the modifications will automatically carry over in the calling sub.

Personally, I am slightly anal when it comes to coding, so I would use a
longer argument list than others might use.
 
T

Tony Jollans

(inline)

--
Enjoy,
Tony

Jean-Guy Marcil said:
The latter is safer, especially when handling more than one document. If
you
always use the Selection object, it will eventually mess things up because
the selection will not be what you think it is. You never have this
problem
with a Range object.

Also, your two statements are different:
Set oRange = Selection.Range
is equal to "", because the Selection is the insertion point.
Whereas
Set oRange = oDoc.Range
is equal to "¶", which is the total range of the oDoc object.

Actually oDoc.Range will be ¶ if the document is blank but that is not
necessarily the case - so it will be whatever the content is for a document
based on your sTemplate.

Because ".Parent" can be anything, Intellisense never offers anything when
you use it (It does not try to determine what the Parent is).
If you need help, what you can do is create a dummy object, in this case a
dummy document object. Then use Intellisense on that dummy object until
you
get what you need. When you have found the syntax you want, just
copy/paste
from the dummy object to the ".Parent" one before deleting the dummy
object.

If you want intellisense you could use oRange.Document - and in general I
would consider being more explicit to be better coding style anyway - I
think the Parent of a Range is always the Document but why take the chance?
 
S

StevenM

Thank you both for your feedback, I think I’m beginning to understand (at
least the basics of) how the range object works. It also dawned upon me that
instead of passing a range object and then recreating its document object
with oRange.Parent, it would be more straightforward to pass the document
object and then create a new range object.

Again, thanks!

Steven Craig Miller
 
J

Jean-Guy Marcil

StevenM said:
Thank you both for your feedback, I think I’m beginning to understand (at
least the basics of) how the range object works. It also dawned upon me that
instead of passing a range object and then recreating its document object
with oRange.Parent, it would be more straightforward to pass the document
object and then create a new range object.

Not necessarily.

The range object may be difficult to recreate.

Personally, I would go with a full parameter list. It may be longer, but it
will be foolproof. Remember that you can have the Sub name on many lines, and
once you have called the sub, you can copy/paste the call and just change the
appropriate data.

For example:

Sub TweakRange(rngSource As Range, _
rngTarget As Range, _
docSource As Document, _
docTarget As Document, _
lngRepeat As Long, _
strTextTitle As String, _
strTextwarning As String)

'Somce code

End Sub

Or:

Sub TweakRange(ByRef rngSource As Range, _
ByVal rngTarget As Range, _
ByVal docSource As Document, _
ByVal docTarget As Document, _
ByVal lngRepeat As Long, _
ByVal strTextTitle As String, _
ByVal strTextwarning As String)

etc.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top