PDA

View Full Version : search for one word when found search another



saban
03-03-2006, 02:13 AM
lets say I have words:

Start
my name is saban
End

Start
my surname is saulic
End


Now I would like to search for word start and when it is found search for word end but this word end should be found before next start word is found (occurs)
any ideas
thnx

TonyJollans
03-03-2006, 07:08 AM
Unfortunately there is no easy way to do this. You must search for "Start" and then look, in separate searches, for "Start" and "End", and see which is earlier in the document (assuming both exist).

fumei
03-03-2006, 04:48 PM
This is the same logic problem as your posts re: <Amend> and </Amend>. No different.

I am still trying to find a (relatively) simple way to do this. There is an exceedingly involved complex way...and frankly, I do not think there IS a simple way.

TonyJollans
03-04-2006, 03:35 AM
The basic logic isn't difficult but it does need multiple searches ...


Sub FindStartEnd()

Dim FoundStart As Range
Dim FoundStartNext As Range
Dim FoundEnd As Range

Selection.HomeKey wdStory

With Selection.Find
.ClearFormatting
.Text = "Start"
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindStop
.Format = True
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With

If Selection.Find.Execute(FindText:="Start") Then
Set FoundStart = Selection.Range.Duplicate
Selection.Collapse wdCollapseEnd
If Selection.Find.Execute(FindText:="Start") Then
Set FoundStartNext = Selection.Range.Duplicate
ActiveDocument.Range(FoundStart.End + 1, FoundStartNext.Start - 1).Select
Else
ActiveDocument.Range(FoundStart.End + 1, ActiveDocument.Range.End).Select
End If
If Selection.Find.Execute(FindText:="End") Then
Set FoundEnd = Selection.Range.Duplicate
ActiveDocument.Range(FoundStart.Start, Selection.End).Select
Else
Selection.Collapse wdCollapseEnd
MsgBox """Start .... End"" not found."
End If
End If

End Sub

(not thoroughly tested)

saban
03-06-2006, 01:54 AM
thnx guys

saban
03-06-2006, 02:04 AM
tonny

It works for one instance of "start" and "end" word but if i have multiple instances it does not

works:
start
blabla
end

does not work:
start
bla bla
end
start
blabla

TonyJollans
03-06-2006, 04:57 AM
It finds the first instance - you will then need to do it again with an appropriate start position. If there is another "start" in the document you will already have found it so use that as a basis for the next Find.

saban
03-06-2006, 07:10 AM
but how do i determine that it searches from next start not from the same one

saban
03-06-2006, 08:10 AM
Sub FindStartEnd()

Dim FoundStart As Range
Dim FoundStartNext As Range
Dim FoundEnd As Range

Selection.HomeKey wdStory

With Selection.find
.ClearFormatting
.Text = "Start"
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindStop
.Format = True
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With

If Selection.find.Execute(FindText:="Start") Then
Set FoundStart = Selection.Range.Duplicate
Selection.Collapse wdCollapseEnd
If Selection.find.Execute(FindText:="Start") Then
Set FoundStartNext = Selection.Range.Duplicate
ActiveDocument.Range(FoundStart.End + 1, FoundStartNext.Start - 1).Select
Else
ActiveDocument.Range(FoundStart.End + 1, ActiveDocument.Range.End).Select
End If
If Selection.find.Execute(FindText:="End") Then
Set FoundEnd = Selection.Range.Duplicate
ActiveDocument.Range(FoundStart.Start, Selection.End).Select
Else
Selection.Collapse wdCollapseEnd
msgbox """Start .... End"" not found."
End If
End If
Selection.Collapse wdCollapseEnd
Do
With Selection.find
.ClearFormatting
.Text = "Start"
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindStop
.Format = True
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With

If Selection.find.Execute(FindText:="Start") Then
Set FoundStart = Selection.Range.Duplicate
Selection.Collapse wdCollapseEnd
If Selection.find.Execute(FindText:="Start") Then
Set FoundStartNext = Selection.Range.Duplicate
ActiveDocument.Range(FoundStart.End + 1, FoundStartNext.Start - 1).Select
Else
ActiveDocument.Range(FoundStart.End + 1, ActiveDocument.Range.End).Select
End If
If Selection.find.Execute(FindText:="End") Then
Set FoundEnd = Selection.Range.Duplicate
ActiveDocument.Range(FoundStart.Start, Selection.End).Select
Else
' Selection.Collapse wdCollapseEnd
msgbox """Start .... End"" not found."
End If
End If
Selection.Collapse wdCollapseEnd
Loop Until FoundStart Is Nothing
End Sub

I guess this does the trick
except there is one problem why does the procedure not stop
I get this infinity loop I guess

Thnx

saban
03-06-2006, 08:44 AM
and one more question

how could be done if "Start" is missing

R_Rajesh
03-07-2006, 06:17 AM
Try this, slightly different approach…

Sub MyTest()
Dim arr1, arr2, i, rng As Range
arr1 = Array("(<End>)(*)(<End>)", "(<Start>)(*)(<Start>)", "(<Start>)(*)(<End>)")
arr2 = Array("<Start>", "<End>", "End,Start", "End,Start")
With Selection
.HomeKey Unit:=wdStory
With .Find
.ClearFormatting: .Replacement.ClearFormatting
.Replacement.Text = "": .Forward = True: .Wrap = 0
.Format = False: .MatchCase = False
.MatchWholeWord = True: .MatchAllWordForms = False
.MatchSoundsLike = False: .MatchWildcards = True
For i = LBound(arr1) To UBound(arr1)
Selection.HomeKey Unit:=wdStory: .Text = arr1(i)
Randomize
While .Execute
If i = UBound(arr1) Then
Selection.Range.HighlightColorIndex = Int((16 * Rnd) + 1)
Else
Set rng = Selection.Range
.Text = arr2(i)
If Not .Execute Then
rng.Words(IIf(i = LBound(arr1), 1, rng.Words.Count)) = _
Split(arr2(i + 2), ",")(0) & vbCrLf & vbCrLf & Split(arr2(i + 2), ",")(1)
End If
Selection.Collapse wdCollapseEnd: .Text = arr1(i)
End If
Wend
Next i
End With
End With
End Sub

Tried it with the following sample and it seems to work. The code tries to guess where the missing "start" or "end" tags are and inserts them. It will fail if "End" tag of one block and "Start" tag of the very next block is missing. Also make sure the very first "Start" and the very last "End" tag is present.
btw how do you use vba tags while posting?


Start
my name is saban

Start
my name is saban

Start
my surname is saulic
End

my name is saban
End

my surname is saulic
End

saban
03-07-2006, 08:35 AM
just press small square with VBA text inside and you will get
<CODE>blbblb</CODE> except the brackets will be [
here

saban
03-07-2006, 09:07 AM
for your previous example how can i exit sub if no start or end is found
I mean when it reachs the end of the document the sub should be stoped

R_Rajesh
03-07-2006, 09:20 AM
Not sure what you mean... As it is the code should stop once it reaches the end (or once it has processed all start/end blocks)
Is it going in a continuous loop or something?

R_Rajesh
03-07-2006, 09:33 AM
Like I said, I am not sure if this is what you want but try replacing this:


rng.Words(IIf(i = LBound(arr1), 1, rng.Words.Count)) = _
Split(arr2(i + 2), ",")(0) & vbCrLf & vbCrLf & Split(arr2(i + 2), ",")(1)


with this



MsgBox arr2(i) & " not found; exiting..."
Exit For

fumei
03-07-2006, 09:44 AM
R_Rajesh - interesting approach.

Your code highlights the chunks, but I am not sure exactly how this fits to the purpose of this post. Could you please redo your code and put comments into it? Just the normal way of doing comments, with the "'". Your comments may make it easier to follow what you are doing.

saban
03-07-2006, 12:15 PM
sorry rajesh it was not your example but tonys
The example tonyjollans posted

But I have a problem how to avoid an error when sub comes till end of the document also gives me an error "Start... end not found" I must avoid this error somehow

any ideas
Thnx

R_Rajesh
03-08-2006, 12:21 AM
>>Now I would like to search for word start and when
>>it is found search for word end

fumei, after reading the above Ii assumed that once the start and end was found, saban wanted to do something with that range so I highlighted them as an example. Looks like I was way off track...

saban
03-08-2006, 01:30 AM
how can be done: when sub reaches the end of the document that it calls another sub or exits one

any ideas
Thnx

saban
03-08-2006, 02:40 AM
just one short question

How can I refer to last character in document?
If I have text like this

blbablablablbalba
c
And when sub reaches this c-(and selects it) or any other character at the end of the document it must be stopped

I am going crazy on this
thnx for all your help

R_Rajesh
03-08-2006, 05:23 AM
You can use this to determine if the current selection extends till the end



If Selection.End = ActiveDocument.Content.End Or _
Selection.End = ActiveDocument.Content.End - 1 Then _
MsgBox "You are at the end"

TonyJollans
03-08-2006, 03:21 PM
saban,

Are you still struggling? What is it you really want to do?

R_Rajesh,

I don't *think* you're way off beam - but I'm really unsure what the requirement is.

saban
03-09-2006, 01:37 AM
You see it is like this

I have a document which contains start and end tags which are xml elements I have text like this

<Amend> My name is saban <Members>12</Members>
it is sunny day :)
</Amend>
<Amend> My name is saban <Members>12</Members>
it is sunny day :)
</Amend>
And with your sub I am checking if every start tag has its end tag

But every time it is checking for start tags and it reachs the end of the document it gives me an error (msgbox) that Start...End not found
But it is at the end of the document so there are no tags left to search, from there I need the sub to call another sub and check for <Members> tags to have a matching pair of start and end tag and so on
When I am checking for end tags it is ok it doesnt give me an error at the end of the document so i can call another sub for further checking but when I look for start tags it gives me an error at the end of the document and sub is stoped so I cant call for another sub for further checking plizz let me know if you dont konw what I am trying to do

Thnx
Saban

R_Rajesh
03-09-2006, 02:41 AM
Not tested...



Sub FindStartEnd()

Dim FoundStart As Range
Dim FoundStartNext As Range
Dim FoundEnd As Range
Dim rng
Selection.HomeKey wdStory

With Selection.Find
.ClearFormatting
.Text = "Start"
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindStop
.Format = True
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With

If Selection.Find.Execute(FindText:="Start") Then
rng = Selection.Range.Start
Set FoundStart = Selection.Range.Duplicate
Selection.Collapse wdCollapseEnd
If Selection.Find.Execute(FindText:="Start") Then
Set FoundStartNext = Selection.Range.Duplicate
ActiveDocument.Range(FoundStart.End + 1, FoundStartNext.Start - 1).Select
Else
ActiveDocument.Range(FoundStart.End + 1, ActiveDocument.Range.End).Select
End If
If Selection.Find.Execute(FindText:="End") Then
Set FoundEnd = Selection.Range.Duplicate
ActiveDocument.Range(FoundStart.Start, Selection.End).Select
Else
Selection.Collapse wdCollapseEnd
MsgBox """Start .... End"" not found."
End If
End If
Selection.Collapse wdCollapseEnd

Do
With Selection.Find
.ClearFormatting
.Text = "Start"
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindStop
.Format = True
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With

If Selection.Find.Execute(FindText:="Start") Then

Set FoundStart = Selection.Range.Duplicate
Selection.Collapse wdCollapseEnd
If Selection.Find.Execute(FindText:="Start") Then
Set FoundStartNext = Selection.Range.Duplicate
ActiveDocument.Range(FoundStart.End + 1, FoundStartNext.Start - 1).Select
Else
ActiveDocument.Range(FoundStart.End + 1, ActiveDocument.Range.End).Select
End If
If Selection.Find.Execute(FindText:="End") Then
Set FoundEnd = Selection.Range.Duplicate
ActiveDocument.Range(FoundStart.Start, Selection.End).Select
Else
' Selection.Collapse wdCollapseEnd
If ActiveDocument.Content.End - Selection.End <> 0 Then
MsgBox """Start .... End"" not found."
Else
MsgBox "Reached the end, call your next procedure"
End If

End If
Else
Exit Do
End If

Selection.Collapse wdCollapseEnd

Loop Until FoundStart Is Nothing
End Sub

saban
03-09-2006, 05:36 AM
thnx I will let you know

fumei
03-09-2006, 10:14 AM
R_Rajesh, If ActiveDocument.Content.End - Selection.End <> 0 Then
MsgBox """Start .... End"" not found."
Else
MsgBox "Reached the end, call your next procedure"
End If will ONLY display the second message ("Reached the end....") if the Selection covers to the end of the document. AND if it does:ActiveDocument.Range(FoundStart.End + 1)will return a Subscript Out of Range error, as FoundStart is the range of the Selection (covering the end of the document), so End of the document + 1 is an error - that number does not exist in the document.

R_Rajesh
03-09-2006, 11:51 PM
fumei,

>>will ONLY display the second message ("Reached the end....") if the Selection covers to the end of the document.

As the messagebox text suggests, that was my intention

>>will return a Subscript Out of Range error

which can only happen if the very last word in the document was the start tag

fumei
03-10-2006, 08:28 AM
But you do not do any error trapping. I tested this, and I could never get the proper messages - except for the first "Start....End not found."

I stepped through it, and it can not ever get to the message "Reached the end". This is because it creates a run-time error of Subscript out of range. If Selection.Find.Execute(FindText:="Start") Then
Set FoundStartNext = Selection.Range.Duplicate
ActiveDocument.Range(FoundStart.End + 1, FoundStartNext.Start - 1).Select
Else
' this errors out, so.....
ActiveDocument.Range(FoundStart.End + 1, ActiveDocument.Range.End).Select
End If
If Selection.Find.Execute(FindText:="End") Then
Set FoundEnd = Selection.Range.Duplicate
ActiveDocument.Range(FoundStart.Start, Selection.End).Select
Else
' Selection.Collapse wdCollapseEnd
If ActiveDocument.Content.End - Selection.End <> 0 Then
' this can NEVER be used
MsgBox """Start .... End"" not found."
Else
MsgBox "Reached the end, call your next procedure"
End If

R_Rajesh
03-10-2006, 10:40 PM
Error trapping... I haven't even tested that code (mentioned in my post)

My intention was to give seban some pointers on implementing the code I posted previously (see if selection extends till the end)

>>and it can not ever get to the message "Reached the end".

Depends on what text you are trying it on. Try this:

Start My name is saban <Members>12</Members>
it is sunny day
End
Start My name is saban <Members>12</Members>
it is sunny day

saban
03-13-2006, 08:05 AM
Thnx guys it helped me a lot

I am almost at the end
Some thing is bothering me
when I had write some code for a toolbar button to show/hide other toolbar It always asks me if I want to save changes to template
I wrote a code for when button is pressed it changes the apparance on it
(ex. when toolbar is visible the text on button says ON/OFF and when toolbar is not visible it says ON/OFF-izključen)

But when I quit word it always asks me if I want to save changes to template, I would very like to avoid this message

thnx

TonyJollans
03-13-2006, 08:24 AM
Making a change to a toolbar does make a change to the containing template but you can effectively tell word to ignore it by doing somethiing like this:

' Assuming myControl is a reference to the control you are changing ...

Set myTemplate = Templates(myControl.Parent.Context)
mySavedState = myTemplate.Saved
' Make your change to your Control
myTemplate.Saved = mySavedState
Set myTemplate = Nothing

saban
03-14-2006, 01:48 AM
ok thnx
I will give it a try

saban
03-14-2006, 01:55 AM
And "myTemplate.Saved" should be refered as ???

How can it be done in this code
Sub vklopiizklopi()

With CommandBars("VSE")
If .Visible = True Then
.Visible = False
CommandBars("Izklopi").Controls(1).State = msoButtonUp
CommandBars("Izklopi").Controls(1).Caption = "ON/OFF izklopjen"
CommandBars("Izklopi").Controls(1).TooltipText = "preverjanje kod izklopljeno"
'CommandBars("Izklopi").Controls(1).BackColor = vbRed
Else
If .Visible = False Then
.Visible = True
CommandBars("Izklopi").Controls(1).State = msoButtonDown
CommandBars("Izklopi").Controls(1).Caption = "ON/OFF"
CommandBars("Izklopi").Controls(1).TooltipText = "preverjanje kod vklopljeno"
End If
End If
End With
end sub

saban
03-14-2006, 03:31 AM
Sub vklopiizklopi()
Dim myTemplate As Object
Dim myControl As Object
Dim mySavedState As Object
Set myControl = CommandBars("Izklopi").Controls(1)
Set myTemplate = Templates(myControl.Parent.Context)
Set mySavedState = myTemplate
'mySavedState = myTemplate.Saved
With CommandBars("VSE")
If .Visible = True Then
.Visible = False
CommandBars("Izklopi").Controls(1).State = msoButtonUp
CommandBars("Izklopi").Controls(1).Caption = "ON/OFF izklopjen"
CommandBars("Izklopi").Controls(1).TooltipText = "preverjanje kod izklopljeno"
'CommandBars("Izklopi").Controls(1).BackColor = vbRed
Else
If .Visible = False Then
.Visible = True
CommandBars("Izklopi").Controls(1).State = msoButtonDown
CommandBars("Izklopi").Controls(1).Caption = "ON/OFF"
CommandBars("Izklopi").Controls(1).TooltipText = "preverjanje kod vklopljeno"
End If
End If
End With
' Make your change to your Control
myTemplate.Save '= mySavedState
Set myTemplate = Nothing
Exit Sub
End Sub

I did it like this and it works :)

Thnx

TonyJollans
03-14-2006, 03:54 AM
Something like this ...

Sub vklopiizklopi()

Dim myTemplate As Object
Dim myControl As Object
Dim mySavedState As Boolean ' <== This is not an object

Set myControl = CommandBars("Izklopi").Controls(1)
Set myTemplate = Templates(myControl.Parent.Context)
mySavedState = myTemplate.Saved

With CommandBars("VSE")
If .Visible = True Then
.Visible = False
With myControl
.State = msoButtonUp
.Caption = "ON/OFF izklopjen"
.TooltipText = "preverjanje kod izklopljeno"
End With
Else ' .Visible MUST be False - no need to check it
.Visible = True
With myControl
.State = msoButtonDown
.Caption = "ON/OFF"
.TooltipText = "preverjanje kod vklopljeno"
End With
End If
End With

myTemplate.Saved = mySavedState
Set myTemplate = Nothing
Set myControl = Nothing

End Sub

saban
03-15-2006, 01:34 AM
thnx
for all your help really appreciate it

Saban