View Full Version : Solved: Weird Selection Behavior
marsy00
09-21-2012, 09:26 AM
Hello,
The following code inserts a new Requirement Tag into my requirements specification document. What I expect is that after the requirement tag is added, the whole tag (which is on its own line) is selected. After the bookmark is added, I collapse the selection to the end of the line.
Set r = Selection.Range
'Add the Requirement Tag
r.InsertAfter reqtag
Selection.MoveEnd unit:=wdLine, Count:=1
Selection.Style = ActiveDocument.Styles("Requirement")
' Add the new requirement tag as a bookmark
With ActiveDocument.Bookmarks
.Add Range:=Selection.Range, Name:=Replace(reqtag, ":", "")
.DefaultSorting = wdSortByName
.ShowHidden = False
End With
Selection.Collapse wdCollapseEnd
r.InsertParagraphAfter
Whats strange is that when I do selection.collapse wdcollapseend, most of the time it does what I expect -- collapse to the end of the current line and insert a new paragraph on the next line. But sometimes (seemingly randomly), it collapses the selection and moves the cursor to the next line (and takes the end of bookmark with it). Then the rest of my code (not displayed) adds the rest of the requirement template, but the whole requirement template is now the bookmark, not just the tag.
I cant determine anything different between the two behaviors when I step through the code. As far as i can tell its random...
Hope that makes sense, any help is appreciated. Thanks!
Frosty
09-21-2012, 11:45 AM
I would try displaying your paragraph marks while stepping through the code to see what's really happening. The .MoveEnd method combined with the wdLine parameter is probably getting you into trouble. You might be *just* at the end of a line and get pushed to the next "line" which is basically just the paragraph mark.
Other than that, you'll need to get beyond the "it seems random" troubleshooting, and perhaps determine a paragraph in a document that it work on and a paragraph it doesn't... and then post that document.
Otherwise, all we can do right now is give you additional guesses.
Good luck!
fumei
09-21-2012, 05:13 PM
It could be the mix of Selection and Range. try to use one - preferably Range.
reqtag is a string variable?
Plus, what exactly are you selecting to start with?
macropod
09-23-2012, 05:24 PM
Perhaps:
Set r = Selection.Range
'Add the Requirement Tag
With r
.InsertAfter reqtag & vbCr
.MoveEnd wdCharacter, -1
.Style = ActiveDocument.Styles("Requirement")
End With
' Add the new requirement tag as a bookmark
ActiveDocument.Bookmarks.Add Range:=r, Name:=Replace(reqtag, ":", "")
marsy00
09-24-2012, 07:44 AM
Thanks all for the suggestions. I rewrote my code similar to what macropod suggested. I do like getting rid of the mix of range and selection objects. But, now I'm running into a different problem.
In the code below, I add two lines, and each line has a different style. But when I execute, both lines end up with the "Affects" style. How do I remove the first line (the "Requirement" style) from the range before I set the next line's style?
With r
.InsertAfter reqtag & vbCr
.MoveEnd unit:=wdCharacter, Count:=-1
.Style = ActiveDocument.Styles("Requirement")
'Add the new requirement tag as a bookmark.
With ActiveDocument.Bookmarks
.Add Range:=r, Name:=Replace(reqtag, ":", "")
.DefaultSorting = wdSortByName
.ShowHidden = False
End With
.Collapse direction:=wdCollapseEnd
.InsertParagraphAfter
'Add the affects tags
.InsertAfter "ILR, Gateway, Phone, GWP, HW, FW, PhysApp, PatApp"
.Style = ActiveDocument.Styles("Affects")
.Collapse direction:=wdCollapseEnd
.InsertParagraphAfter
End With
Thanks for the help!!
fumei
09-24-2012, 11:28 AM
As long as you are using the same object (r) for both in the same With, you can not. The last Style is applied to both.
I am not sure if it will work - I am having computer problems so I can not test - but using Duplicate may work.
Guys?
Frosty
09-24-2012, 01:47 PM
there are two options -- 1) redefine the range you're working with or 2) redine the area within the range you want to apply the style to.
Just to be clear: "lines" has a different meaning than "paragraph" -- even if your paragraph is a single line.
Is your "Affects" style a paragraph style or a character style?
when you use a With block, you are attempting to apply something to the entire range. But you could change your second .Style line from:
.Style = ActiveDocument.Styles("Affects")
to
.Paragraphs.Last.Style = ActiveDocument.Styles("Affects")
I don't think this is necessarily the best way to do it, but it would reduce your application of the style from the entire range, to the last paragraph in that range, which may work for your scenario.
.Duplicate is a very useful function, but I'm not sure it would apply here without the OP understanding ranges a bit better.
Let us know how it goes...
fumei
09-24-2012, 02:08 PM
.Duplicate is a very useful function, but I'm not sure it would apply here without the OP understanding ranges a bit better.
Agreed.
Quote marsy00: "
Whats strange is that when I do selection.collapse wdcollapseend, most of the time it does what I expect -- collapse to the end of the current line "
What Frosty is trying to say (if I may put words in his mouth) is that this statement is conceptually false. No, it does not. It does exactly what it says it does. It collapses the Selection to its end...whatever that may be. It has NO relation to the end of the current line, or paragraph or anything. It makes the Selection into an Insertion Point just to the right of the last character of the Selection.
Ranges are a critical topic in Word, and understanding them vastly expands your ability to manipulate Word. They are both very simple, and tricky.
Frostys two suggestion are good, although I think #1 would work easier.
You could also possibly use the range (r) for the first part, collapse it, and switch to Selection.
With r
.InsertAfter reqtag & vbCr
.MoveEnd unit:=wdCharacter, Count:=-1
.Style = ActiveDocument.Styles("Requirement")
'Add the new requirement tag as a bookmark.
With ActiveDocument.Bookmarks
.Add Range:=r, Name:=Replace(reqtag, ":", "")
.DefaultSorting = wdSortByName
.ShowHidden = False
End With
.Collapse direction:=wdCollapseEnd
End With
Selection.Range = r
set r = nothing
With Selection
.InsertParagraphAfter
.Style = ActiveDocument.Styles("Affects")
'Add the affects tags
.TypeText "ILR, Gateway, Phone, GWP, HW, FW, PhysApp, PatApp"
.Collapse direction:=wdCollapseEnd
.InsertParagraphAfter
End WithThis may be a case where it would be a good idea to explicitly destroy the range object...
macropod
09-24-2012, 08:33 PM
I'd be inclined to approach it a bit differently:
'Point to the selected range
Set r = Selection.Range
'Add the Requirement Tag
With r
.InsertAfter reqtag & vbCr
'Exclude the last para we created
.MoveEnd wdCharacter, -1
'Apply the desired Style
.Style = ActiveDocument.Styles("Requirement")
'Add the new requirement tag as a bookmark
ActiveDocument.Bookmarks.Add Range:=r, Name:=Replace(reqtag, ":", "")
'Get the last para we created
.MoveEnd wdCharacter, 1
.Collapse wdCollapseEnd
'Add the affects tags
.InsertAfter "ILR, Gateway, Phone, GWP, HW, FW, PhysApp, PatApp" & vbCr
'Exclude the last para we created
.MoveEnd wdCharacter, -1
'Apply the desired Style
.Style = ActiveDocument.Styles("Affects")
'Get the last para we created
.MoveEnd wdCharacter, 1
.Collapse direction:=wdCollapseEnd
'Move our selection to the last character
.Select
End With
fumei
09-24-2012, 09:04 PM
And thus the many-worlds interpretation of VBA.
http://en.wikipedia.org/wiki/Many-worlds_interpretation
marsy00
09-25-2012, 07:03 AM
I'd be inclined to approach it a bit differently:
Thanks macropod, that works! But, I dont really understand why... There are a couple .moveEnd lines that are different than in my code in post #5, but I'm not clear how they affect the behavior. Someone said in one of the other posts that I dont have a full understanding of the range object, which is certainly true. Can anyone suggest a site that explains it well? I havent found much, and I've mainly just been kludging my way through MSDN...
Thanks everyone for all the help!
macropod
09-25-2012, 03:12 PM
The Movened lines varously reduce and extend the range covered by 'r'.
As you'll see, I don't have the '.InsertParagraphAfter' line. That's because I used '& vbCr' on a previous line to do the same thing. Then, because I didn't want to format those new paragraphs, I used '.MoveEnd wdCharacter, -1' to temporarily exclude them from the range being processed. Of course, I then had to extend the range again for the next step in the process.
As for sites that explain vba well - I don't think you'll find one that does all you might be interested in. FWIW, a lot of my learning has come through studying code on sites like this and, as I rarely need much vba for myself, helping others to solve their problems.
marsy00
09-27-2012, 12:55 PM
Hello Again,
So, I'm still trying to figure out exactly how the range object behaves. I've run into another question that I hope someone can help me with.
Below I paste one requirement from my document. I've added the styles in {} since I cant paste the actual word content into here.
SYS:0089 {Style = Requirement}
HW, FW {Style = Affects}
Example Requirement. This requirement is based on: {Style = Normal}
• IEC 60601-1, Subclause 6.3.1 {Style = Standards Char}
• IEC 45502-1, Subclause 15.6 {Style = Standards Char}
[Trace Tag] {Style = Trace}
§
Now, what I want to do is generate a report in Excel that lists each requirement in the document and parses the content into columns based on style. I have it working using the Find object, but it only finds the first item in the requirement with the given style. For example, the above requirement would only return the first bullet for the Standards style.
In my code below, the commented out block (near the bottom) is the functional code that only returns the one bullet. The code just below that is what I used to try to return both bullets. But, the problem is that when I use the do loop, the .find is executing on the entire document (i.e. its parsing the entire document full of requirements, not just the one requirement that I'm trying to work with). I thought that my r.MoveEndUntil cset:="§" limited the range to just the one requirement.
Any help is greatly appreciated! Thanks!
Private Function getReqData(req As String, toGet As String) As String
Dim r As Range
Dim i
Set r = ActiveDocument.Range
i = 0
' Find the requirement "req" in the document.
With r.find
.ClearFormatting
.Style = ActiveDocument.Styles("Requirement")
.Text = req
.Replacement.Text = ""
.Forward = True
.Format = True
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
.Wrap = wdFindStop
If .Execute = True Then
'Once found, exit the with block and find the "toGet" style.
Else
'If the requirement wasnt found, then exit the function (error condition).
getReqData = "ERROR:NOT FOUND"
Exit Function
End If
End With
' Expand the range to include the entire requirement.
r.MoveEndUntil cset:="§"
' Find the item in the requirement with the style = toGet.
With r.find
.ClearFormatting
.Style = ActiveDocument.Styles(toGet)
.Text = ""
.Replacement.Text = ""
.Forward = True
.Format = True
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
.Wrap = wdFindStop
' If .Execute = True Then
' getReqData = r.Text
' End If
Do While .Execute = True
If i = 0 Then
getReqData = r.Text
Else
getReqData = getReqData & vbCr & r.Text
End If
i = i + 1
Loop
End With
End Function
fumei
09-27-2012, 01:41 PM
marsy00, it would be much better, when you have followup question,s to start a new thread. This questions has nothing to do with "Weird Selection Behaviour". You will get abetter response.
And if THIS thread question/subject is answered, please mark the thread as Solved.
marsy00
09-27-2012, 01:52 PM
marsy00, it would be much better, when you have followup question,s to start a new thread. This questions has nothing to do with "Weird Selection Behaviour". You will get abetter response.
And if THIS thread question/subject is answered, please mark the thread as Solved.
I was thinking about that right after I posted. I agree and will mark this as solved and repost.
Thanks
Powered by vBulletin® Version 4.2.5 Copyright © 2025 vBulletin Solutions Inc. All rights reserved.