PDA

View Full Version : Selection and Range



KeyCode
12-01-2008, 03:22 AM
Hi all.

I am trying to save current Selection.Range in Line for later use.
But when I try to transfer that saved range into Selection at line 3, Line object gets changed. Why is that so?
And what is difference between
Selection.Range = Line
and
Selection = Line.

Sub test()
Set Line = Selection.Range
Selection.Range = Line
MsgBox ("end")
End Sub

TonyJollans
12-01-2008, 05:58 AM
I don't really understand what you're asking, but perhaps this will help you understand:

Firstly, for many purposes - including yours here - Selection and Selection.Range are the same.

Secondly, how you reference either of them, or even objects in general, affects what you get, so:

Set Line = Selection

.. sets Line to be an Object variable, representing the Selection, while:

Line = Selection

.. assigns the default property of the Selection (its Text) to the Line variable.

Sometimes it doesn't matter which you use (although it's generally best to be specific), other times it does make a difference.

KeyCode
12-01-2008, 08:19 AM
Thank you for your answer and now to clerify my question.

If you place brakepoint at line:

Selection.Range = Line

and add watches then after line executes Line.Start and Line.End are changed?

Program behavies differently if I use

Selection = Line.

TonyJollans
12-01-2008, 11:40 AM
I'm afraid I'm not understanding. I don't see a difference.

There is, however, a subtle difference between Set Line = Selection (which keeps a link between Line and Selection) and Set Line = Selection.Range (which creates an independent Range object).

What are you actually trying to do?

fumei
12-01-2008, 11:55 AM
KeyCode, please be clear and specific. It would also help if you:

1. showed us some actual code
2. explained precisely what you are trying to do.

You can start by telling us WHAT you are declaring "Line" as. An Object, or explicitly a Range.

As Tony mentions, using Set means setting an OBJECT as something. Therefore, again as Tony mentions, there is difference between:

Set Line = Selection

and

Set Line = Selection.Range

The first sets a Selection object (with all attending properties and methods).

The second sets a Range object (which does NOT have all the attending Selection properties)

Although there are great many similarities between Selection and Range, they are not the same.

Further;

"Selection.Range = Line

and add watches then after line executes Line.Start and Line.End are changed?"

Technically speaking, if Line is a Range object, then:

Selection.Range = Line

would change the .Start and .End of the Selection. Not Line.Start and Line.End.

Selection.Range = Line

passes the .Start and .End (assuming it IS a Range) values of Line to Selection. The Selection should now have the values of Line (again assuming it IS a Range object).

KeyCode
12-02-2008, 02:59 AM
Fumei, I have given complete code.
It is the one that starts with Sub test() and ends with End Sub :)

Type something in Word, select it, go to visual basic editor, paste code, add brakepoint and watches.

I was also expecting what you said but watches show that line
Selection.Range = Line
changes Line.Start and Line.End which is the whole point of my post.

I am using Office 2003 SP2.

TonyJollans
12-02-2008, 11:27 AM
I think both Gerry and I have been struggling to understand what the real question is here. Your original question was:

And what is difference between
Selection.Range = Line
and
Selection = Line.
.. to which the answer is: None; both statements change the text at the Selection.

What I'm beginning to believe is that you are asking something else, about changes that you were not expecting to your "Line" variable, which, depending on what it is, may occur as a result of changes in the Selection.

If the purpose of your code requires you to save the text of the selection for later use, then save that text (as a String variable). If you need to save formatted text, it can be more awkward. I'll ask again what I asked before: what are you actually trying to do?

Gerry,

On a slightly related note I am working on some code to compare formatted AutoCorrects. Have you ever tried to do such a thing, or do you have any thoughts on how best it might be done?

fumei
12-02-2008, 01:19 PM
"Fumei, I have given complete code.
It is the one that starts with Sub test() and ends with End Sub "

Really? Well that is a useless piece of code as all it does is display "end" in a messagebox.

All it does - regardless of the Selection - is make one = the other, then the other equal the first.

Line = Selection.Range
Selection.Range = Line

Further, as has been asked a couple of times, it depends on what you are declaring Line as. For example, if you declared Line as a Selection....
Sub test()
Dim Line As Selection
Set Line = Selection.Range
Selection.Range = Line
MsgBox ("end")
End Sub
It would fails as error 13 Type Mistmatch. If you declared it as a Range....
Sub test()
Dim Line As Range
Set Line = Selection.Range
Selection.Range = Line
MsgBox ("end")
End Sub
It would not fail, but again, ALL it does is display a messagebox.

If you declared it as an Object....
Sub test()
Dim Line As Object
Set Line = Selection.Range
Selection.Range = Line
MsgBox ("end")
End Sub
It would not fail, but again, ALL it does is display a messagebox.

If you declared as "blank", it becomes a Variant....
Sub test()
Dim Line
Set Line = Selection.Range
Selection.Range = Line
MsgBox ("end")
End Sub
It would not fail, but again, ALL it does is display a messagebox.

Who cares what the breakpoints and watches are saying if what you are DOING is meaningless. I keep on trying to find out what you are trying to DO. I will repeat Tony's post above, and I suggest you focus on what I have bolded.



I think both Gerry and I have been struggling to understand what the real question is here. Your original question was:

" And what is difference between
Selection.Range = Line
and
Selection = Line. "

.. to which the answer is: None; both statements change the text at the Selection.

What I'm beginning to believe is that you are asking something else, about changes that you were not expecting to your "Line" variable, which, depending on what it is, may occur as a result of changes in the Selection.

If the purpose of your code requires you to save the text of the selection for later use, then save that text (as a String variable). If you need to save formatted text, it can be more awkward. I'll ask again what I asked before: what are you actually trying to do?"

Look, I am not trying to be difficult, or be hyper-critical, or be anything negative at all. I am actually trying to help. You are not listening.

WHAT is Line? I have asked. Tony has asked. You are likely not using Option Explicit, and I strongly recommend you start doing so. It forces you to declare variables.


I have put breakpoints on every instruction of your code. I have put Watches on erveything in your code. And...

what are you trying to do again?

Tony, I am not clear on what you are asking.

You are comparing inserted AutoCorrects? No, you can not be doing that. "Inserted" AutoCorrects are not really inserted. They do not exist in the document once the original text is "corrected".

So you want to compare the format of AutoCorrect entries? No can do, as at least as far as 2003. Don't know about 2007. AutoCorrectEntry does not have any format property. It takes the format of the Range (most commonly Selection.Range) at the time of creation. Those properties are not later exposed to VBA...as they do not exist. Did you read the Help on AutoCorrect?


Note If you want to change an AutoCorrect entry that contains a long passage of text, a graphic, or its original formatting, first insert the entry in a document. Then make the changes you want, select the revised entry, and click AutoCorrect Options on the Tools menu. Type the AutoCorrect entry's name in the Replace box, and then click Replace.My bolding. In other words, recreate it.

Obvious Word must hold those values somewhere, how else could it apply them when you use AutoCorrect? But, AFAIK, the format values for an AutoCorrect Entry (once stored as RichText:=True) are not exposed to VBA.

It does NOT store the format of a created AutoCorrect as a named style if the AutoCorrect entry was created from a text string using a character style. It is stored as the individual format values of the range used for the AutoCorrect.

It DOES store the style of the range used to create the AutoCorrectEntry if, and ONLY if, the range used includes the paragraph mark. This makes sense, as the paragraph contains the Style data.

If you make an AutoCorrect of only part of a paragraph - even if it is a specific style - then the format will match the style, but it will NOT show as that named style.

If the entry does include the paragraph mark, then it DOES show as the named style.

However, as that wee bit of information can only really be used within code after the fact - the AutoCorrect has functioned - I don't think this is what you are trying to get at. If I understand correctly, you are trying to compare the entries themselves.

Let me know how it goes. I would be very interested if you succeed in getting a useful compare between entries themselves. At this point, I do not think it is possible, but if anyone can do it, you can.

Caveat: yes, yes, you could of course do it by making a hidden new document, dumping in the comparing AutoCorrects, and then using brute force comparisons of format, and returning that evaluation. I am assuming you are trying to get a more...elegant?...solution.

fumei
12-02-2008, 01:46 PM
Tony, I could have phrased that more simply.

AutoCorrectEntries themselves do not have a Range. Therefore no data that can be extracted from a Range is exposed.

Paragraphs.Count for example.

AutoCorrect "yadda1" =

Blah blah blah.

AutoCorrect "yadda2" =

Blah blah blah. More blah.
Another paragraphs here.
And yet another.

There is no way to find out that "yadda1" has 1 paragraph, and "yadda2" has 3.

Same thing with format.

AutoCorrect "yadda1" =

Blah blah blah.

AutoCorrect "yadda2" =

Blah blah blah. More blah.
Another paragraphs here.
And yet another.

There is no Range.Font.Bold = True exposed from "yadda1", and therefore there is no way to determine that "yadda1" is bold, and "yadda2" is not.

TonyJollans
12-02-2008, 02:05 PM
Thanks, Gerry. I don't want to hi-jack this thread (the only relationship to it is the non-existence of Ranges as standalone constructs), so just a brief reply here - if I want more, I'll start a new thread.

The AutoCorrects I want to compare are in two different applications so I'm having to copy them using Automation, and I am doing it in 2007 - but I don't think this aspect of it is any different from earlier versions. It's everything you say and I have done just what you say in your last paragraph, except that I use Document Compare and check the Revisions Count - and, yes, I would prefer something less convoluted, shall we say, and perhaps better performing as well. I am still unsure whether it will work in all cases.

fumei
12-02-2008, 03:47 PM
"the only relationship to it is the non-existence of Ranges as standalone constructs"

VERY well put. That is exactly what the OP seems to be having problems with. Actually, the non-existence of Ranges is not a construct of ANY sort...standalone or other wise.

:funnyashe

Yes...well. Dumping them into document and using Document Compare seems rather heavy-handed. Brute force. "better performing"...crack me up. Yes, I imagine doing it that way is not exactly a nice slim, trim, elegant bit of processing. And yes, I can see that some things could slip by.

Why do you need to even do this? Never mind. If you feel like it, post a new thread; as you are correct, we have hi-jacked this.

KeyCode
12-03-2008, 07:15 AM
I can't beleive this!!

I just wanted to know why following line in my subroutine changes Line.End and Line.Start as is shown by using watches:

Selection.Range = Line

Is it a bug or can it be explained by some VBA mechanics I am not aware of?

TonyJollans
12-03-2008, 10:07 AM
The behaviour is not documented anywhere, so it is pretty hard to say that anything is a bug, and pretty hard to say why anything happens. All one can really do is observe what happens, and what happens with your code is that the text in the Range is, in effect, deleted, and the replacement text is added after it.

fumei
12-03-2008, 12:41 PM
It is NOT a bug. It is doing precisely what it is told to do. If you find it unbelievable then you are not paying attention.

What I find unbelievable is you have not the courtesy to answer any of the repeadly questions asked of you. If you had it would be much easier to explain it to you, to help you understand why it is doing what it is doing.

I will repeat. It is NOT a bug, and it is doing precisely - and correctly - what it is told to do.

"Is it a bug or can it be explained by some VBA mechanics I am not aware of?"

It is the latter. We have been trying to explain some of the mechanics, but...shrug. Your being not aware is at least partially because you are not listening, and not bothering to answer repeated questions.

I hope you will eventually figure it out.

Good luck.

fumei
12-03-2008, 12:57 PM
As a final comment:

In your code, if you have:
Selection.Range = Line

Yes, Line.Start (and Line.End) will change. This is NOT a bug. This is the correct thing for VBA to do.

If instead you have:
Selection.Range.Start = Line.Start
Selection.Range.End = Line.End
then Line.Start and Line.End will NOT change. This is also the correct thing for VBA to do.

fumei
12-03-2008, 01:30 PM
Also, if you have:
Selection = Line

then Line.Start or Line.End also will not change. Which is ALSO correct for VBA to do.

I don't know why I am bothering.

TonyJollans
12-03-2008, 02:21 PM
You really should have stopped at your final comment :)

Whether Line.End changes depends upon the variable type of Line - whether Line is set to Selection or Selection.Range - not on whether Selection or Selection.Range is set to Line.

fumei
12-03-2008, 02:45 PM
"not on whether Selection or Selection.Range is set to Line"

Ummmm. Not quite. The OP code does set Line to Selection.Range:Set Line = Selection.Range
Selection.Range = Line



and if it is......

Selection.Range = Line (Line.Start changes)
Selection = Line (Line.Start does NOT change)

Which is why I mentioned that:


Selection = Line
is different.

TonyJollans
12-03-2008, 03:04 PM
If you are seeing that then I have no explanation at all. To confirm, tell me the output from this:

Sub test()
Debug.Print "using Selection.Range = Line"
ActiveDocument.Range(100, 200).Select
Set Line = Selection.Range
Debug.Print Line.Start & vbTab & Line.End
Selection.Range = Line
Debug.Print Line.Start & vbTab & Line.End
Debug.Print "using Selection = Line"
ActiveDocument.Range(100, 200).Select
Set Line = Selection.Range
Debug.Print Line.Start & vbTab & Line.End
Selection = Line
Debug.Print Line.Start & vbTab & Line.End
End Sub

KeyCode
12-04-2008, 04:34 AM
Thank you Tony for trying.
Here is output:

using Selection.Range = Line
100 200
100 100
using Selection = Line
100 200
100 100

TonyJollans
12-04-2008, 07:56 AM
That is exactly what I see - in other words, no difference between

Selection.Range = Line

and

Selection = Line

What makes a difference is what "Line" is.

fumei
12-04-2008, 10:39 AM
That is only the output under certain conditions...which we have repeatedly asked about. Depending (as has been mentioned) WHAT Line is declared as (if at all), those numbers can change.

Here is an output - copied directly from the Immediate Window:

using Selection.Range = Line
100 200
100 100
using Selection = Line
100 200
100 200

Bolding added.

Different. In fact, I can get those DIFFERENT values under three different circumstances.

TonyJollans
12-04-2008, 07:31 PM
You can/do get those results without changing the code - in other words without declaring Line as it was not declared in the original. I'm not trying to be difficult, really I'm not <g> and I'm quite sure we're saying the same thing in different ways.