Vba word selection find if not found

I’ve created a MS Word macro that searches for certain text (indicated by markup codes), cuts the text and inserts it into a new footnote, and then deletes the markup codes from the footnote. Now I want the macro to repeat until it doesn’t find any more markup codes in the text.
Here’s the macro below

Sub SearchFN()

'find a footnote
Selection.Find.ClearFormatting
With Selection.Find
    .Text = "&&FB:*&&FE"
    .Replacement.Text = ""
    .Forward = True
    .Wrap = wdFindContinue
    .Format = False
    .MatchCase = False
    .MatchWholeWord = False
    .MatchKashida = False
    .MatchDiacritics = False
    .MatchAlefHamza = False
    .MatchControl = False
    .MatchByte = False
    .MatchAllWordForms = False
    .MatchSoundsLike = False
    .MatchFuzzy = False
    .MatchWildcards = True
End With
Selection.Find.Execute

'cut the footnote from the text
Selection.Cut

'create a proper Word footnote
With Selection
    With .FootnoteOptions
        .Location = wdBottomOfPage
        .NumberingRule = wdRestartContinuous
        .StartingNumber = 1
        .NumberStyle = wdNoteNumberStyleArabic
    End With
    .Footnotes.Add Range:=Selection.Range, Reference:=""
End With

'now paste the text into the footnote
Selection.Paste

'go to the beginning of the newly created footnote
'and find/delete the code for the start of the note (&&FB:)
    Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
With Selection.Find
    .Text = "&&FB:"
    .Replacement.Text = ""
    .Forward = False
    .Wrap = wdFindContinue
    .Format = False
    .MatchCase = False
    .MatchWholeWord = False
    .MatchKashida = False
    .MatchDiacritics = False
    .MatchAlefHamza = False
    .MatchControl = False
    .MatchByte = False
    .MatchAllWordForms = False
    .MatchSoundsLike = False
    .MatchFuzzy = False
    .MatchWildcards = True
End With
Selection.Find.Execute
With Selection
    If .Find.Forward = True Then
        .Collapse Direction:=wdCollapseStart
    Else
        .Collapse Direction:=wdCollapseEnd
    End If
    .Find.Execute Replace:=wdReplaceOne
    If .Find.Forward = True Then
        .Collapse Direction:=wdCollapseEnd
    Else
        .Collapse Direction:=wdCollapseStart
    End If
    .Find.Execute
End With

'do same for ending code (&&FE)
With Selection.Find
    .Text = "&&FE"
    .Replacement.Text = ""
    .Forward = True
    .Wrap = wdFindContinue
    .Format = False
    .MatchCase = False
    .MatchWholeWord = False
    .MatchKashida = False
    .MatchDiacritics = False
    .MatchAlefHamza = False
    .MatchControl = False
    .MatchByte = False
    .MatchAllWordForms = False
    .MatchSoundsLike = False
    .MatchFuzzy = False
    .MatchWildcards = True
End With
Selection.Find.Execute
With Selection
    If .Find.Forward = True Then
        .Collapse Direction:=wdCollapseStart
    Else
        .Collapse Direction:=wdCollapseEnd
    End If
    .Find.Execute Replace:=wdReplaceOne
    If .Find.Forward = True Then
        .Collapse Direction:=wdCollapseEnd
    Else
        .Collapse Direction:=wdCollapseStart
    End If
    .Find.Execute
End With

Selection.HomeKey Unit:=wdStory
'now repeat--but how??    

End Sub

shA.t's user avatar

shA.t

16.4k5 gold badges53 silver badges111 bronze badges

asked Nov 20, 2012 at 2:24

OutThere's user avatar

Good question this one, you can loop through the whole document using the Selection.Find.Found result.

What you do is start a search and if you find a result go into a loop only while the Selection.Find.Found result is true. Once you’ve got through these, you’re done. The following code should do the trick nicely for you.

Sub SearchFN()
    Dim iCount As Integer

    'Always start at the top of the document
    Selection.HomeKey Unit:=wdStory

    'find a footnote to kick it off
    With Selection.Find
        .ClearFormatting
        .Text = "&&FB:*&&FE"
        .Replacement.Text = ""
        .Forward = True
        .Wrap = wdFindContinue
        .Format = False
        .MatchCase = False
        .MatchWholeWord = False
        .MatchKashida = False
        .MatchDiacritics = False
        .MatchAlefHamza = False
        .MatchControl = False
        .MatchByte = False
        .MatchAllWordForms = False
        .MatchSoundsLike = False
        .MatchFuzzy = False
        .MatchWildcards = True
        .Execute
    End With

    'If we find one then we can set off a loop to keep checking
    'I always put a counter in to avoid endless loops for one reason or another
    Do While Selection.Find.Found = True And iCount < 1000
        iCount = iCount + 1

        'Jump back to the start of the document.  Since you remove the
        'footnote place holder this won't pick up old results
        Selection.HomeKey Unit:=wdStory
        Selection.Find.Execute

        'On the last loop you'll not find a result so check here
        If Selection.Find.Found Then

            ''==================================
            '' Do your footnote magic here
            ''==================================

            'Reset the find parameters
            With Selection.Find
                .ClearFormatting
                .Text = "&&FB:*&&FE"
                .Replacement.Text = ""
                .Forward = True
                .Wrap = wdFindContinue
                .Format = False
                .MatchCase = False
                .MatchWholeWord = False
                .MatchKashida = False
                .MatchDiacritics = False
                .MatchAlefHamza = False
                .MatchControl = False
                .MatchByte = False
                .MatchAllWordForms = False
                .MatchSoundsLike = False
                .MatchFuzzy = False
                .MatchWildcards = True
            End With
        End If
    Loop
End Sub

answered Jan 13, 2013 at 23:20

CuberChase's user avatar

CuberChaseCuberChase

4,4305 gold badges33 silver badges52 bronze badges

This can be done without using Do while(lots of extra lines, and space/time wastage), It could be as simple as follows:

Sub SearchFN()

    'Start from The Top
    Selection.HomeKey Unit:=wdStory

    'Find the first search to start the loop
    Do
    With Selection.Find
        .ClearFormatting
        .Replacement.ClearFormatting
        .Text = "&&FB:*&&FE"
        .Replacement.Text = ""
        .Forward = True
        .Wrap = wdFindstop
        .Format = False
        .MatchCase = False
        .MatchWholeWord = False
        .MatchKashida = False
        .MatchDiacritics = False
        .MatchAlefHamza = False
        .MatchControl = False
        .MatchByte = False
        .MatchAllWordForms = False
        .MatchSoundsLike = False
        .MatchFuzzy = False
        .MatchWildcards = True
        .Execute
    End With

    'If we found the result then loop started
    If Selection.Find.Found Then

            '' Do your work here
            ' Always end your work after the first found result
            ' else it will be endless loop

    Else
    'If we do not found any then it will exit the loop
    Exit Do
    End If
    Loop

End Sub

answered Jun 22, 2018 at 5:51

VBAbyMBA's user avatar

VBAbyMBAVBAbyMBA

7862 gold badges11 silver badges27 bronze badges

The simplest way to do this is to make the function recursive (the function recalls itself). Add this one line to the bottom of your sub or function:

If (Selection.Find.Found = True) then call SearchFN

answered Jun 8, 2019 at 21:13

SendETHToThisAddress's user avatar

INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Contact US

Thanks. We have received your request and will respond promptly.

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!

  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It’s Free!

*Tek-Tips’s functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Students Click Here

Selection.Find Function

Selection.Find Function

(OP)

29 Dec 03 13:32

I’m working with the Selection.Find function in MS Word VBA.  Is it possible to implement an If THEN ELSE statement that performs one thing if data is found, or another thing if no data is not found?  My code is below.

Sub FindCustID
With Selection.Find
     .Text = «Cust ID: ????»
‘???? are 4 wildcards representing the customer ID
     .Replacement.Text = «»
     .Forward = True
     .Wrap = wdFindStop
     .Format = False
     .MatchCase = False
     .MatchWholeWord = False
     .MatchWildcards = True
     .MatchSoundsLike = False
     .MatchAllWordForms = False
    End With
    Selection.Find.Execute

IF DATA IS FOUND………
    Do something

IF DATA IS NOT FOUND…..
    Do something else

End Sub

Thanks.


Mike

Why make it simple and efficient when it can be complex and wonderful?

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Join Tek-Tips® Today!

Join your peers on the Internet’s largest technical computer professional community.
It’s easy to join and it’s free.

Here’s Why Members Love Tek-Tips Forums:

  • Tek-Tips ForumsTalk To Other Members
  • Notification Of Responses To Questions
  • Favorite Forums One Click Access
  • Keyword Search Of All Posts, And More…

Register now while it’s still free!

Already a member? Close this window and log in.

Join Us             Close

Multiple objectsFind
Multiple objects

Represents the criteria for a find operation. The properties and methods of the Find object correspond to the options in the Find and Replace dialog box.

Using the Find Object

Use the Find property to return a Find object. The following example finds and selects the next occurrence of the word «hi.»

With Selection.Find
    .ClearFormatting
    .Text = "hi"
    .Execute Forward:=True
End With
		

The following example finds all occurrences of the word «hi» in the active document and replaces the word with «hello.»

Set myRange = ActiveDocument.Content
myRange.Find.Execute FindText:="hi", ReplaceWith:="hello", _
    Replace:=wdReplaceAll
		

Remarks

If you’ve gotten to the Find object from the Selection object, the selection is changed when text matching the find criteria is found. The following example selects the next occurrence of the word «blue.»

Selection.Find.Execute FindText:="blue", Forward:=True
		

If you’ve gotten to the Find object from the Range object, the selection isn’t changed when text matching the find criteria is found, but the Range object is redefined. The following example locates the first occurrence of the word «blue» in the active document. If «blue» is found in the document, myRange is redefined and bold formatting is applied to «blue.»

Set myRange = ActiveDocument.Content
myRange.Find.Execute FindText:="blue", Forward:=True
If myRange.Find.Found = True Then myRange.Bold = True
		

Казанский, УРААААААААААА!!!))) Я сделал сам!! может есть какие нибудь замечания или предложения??

Если не находит слово»партия», начинает искать слово» серийный» (а найдет полюбому если нет партии), запускает макрос2
а если находит слово «партия»- сразу запускает макрос1

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
Sub Макрос3()
'
' Макрос3 Макрос
'
'
    Selection.Find.ClearFormatting
    With Selection.Find
        .Text = "партия"
        .Replacement.Text = ""
        .Forward = True
        .Wrap = wdFindContinue
        .Format = False
        .MatchCase = False
        .MatchWholeWord = False
        .MatchWildcards = False
        .MatchSoundsLike = False
        .MatchAllWordForms = False
    End With
    
    If Not Selection.Find.Execute Then
    Selection.Find.ClearFormatting
    With Selection.Find
        .Text = "Серийный"
        .Replacement.Text = ""
        .Forward = True
        .Wrap = wdFindContinue
        .Format = False
        .MatchCase = False
        .MatchWholeWord = False
        .MatchWildcards = False
        .MatchSoundsLike = False
        .MatchAllWordForms = False ' если не нашли слово серийный
      End With
      Selection.Find.Execute
      Application.Run MacroName:="Макрос2_для_серийного"
    
      Exit Sub
    End If
    Application.Run MacroName:="Макрос1для_партии"

Добавлено через 1 час 5 минут
Нашелся недостаток такого решения. На каждой точке разветвления( выбора из 2 вариантов) приходится создавать дополнительные подмакросы. У меня в проекте может быть до 5 выборов, это что , это загружать проект 15 макросами? Кол-во растет в геометрической прогресси…. видимо нужно искать другой выход

Добавлено через 19 минут
Видоизмененный рабочий код. Не могу объяснить практически.. просто перебирал вариант на протяжении полу часа)) Вторую функци «if» надо выделить концовкой «end if», а первый вариант, по окончанию первого варианты событий. Тем самым мы прописываем ту разницу в выборе, что нам нужно, а общий макрос идет дальше для 2 вариантов. Ньанс в том, что главное Если у нас не будет «слово1» он начнет искать «слово2» и выполнит его действие. Но если он не найдет слово2, то все равно выполнит его действие.

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
Sub Макрос3()
'
' Макрос3 Макрос
'
'
    Selection.Find.ClearFormatting
    With Selection.Find
        .Text = "партия"
        .Replacement.Text = ""
        .Forward = True
        .Wrap = wdFindContinue
        .Format = False
        .MatchCase = False
        .MatchWholeWord = False
        .MatchWildcards = False
        .MatchSoundsLike = False
        .MatchAllWordForms = False
    End With
    If Selection.Find.Execute Then
    Application.Run MacroName:="Макрос1для_партии"
    End If
    If Not Selection.Find.Execute Then
    Selection.Find.ClearFormatting
    Selection.Find.Replacement.ClearFormatting
    With Selection.Find
        .Text = "серийный"
        .Replacement.Text = ""
        .Forward = True
        .Wrap = wdFindContinue
        .Format = False
        .MatchCase = False
        .MatchWholeWord = False
        .MatchWildcards = False
        .MatchSoundsLike = False
        .MatchAllWordForms = False
    End With
    Selection.Find.Execute
    Application.Run MacroName:="Макрос2_для_серийного"
      End If
        Selection.EndKey Unit:=wdStory
        Selection.TypeParagraph
        Selection.TypeText Text:="конец строки"
    Selection.TypeParagraph
    
    
End Sub

Добавлено через 15 минут
Пишу каждые 20 минут, не уверен что меня не накажут, но я решил всю проблему. Ставлю окончательный вариант кода, где 3 переменных («партия», «серийного», «еди») При нахождении (в порядке очередности) переменной выполняет указанную для нее процедуру, а остальные пропускают, вплоть до завершения вариативной части.

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
Sub Шаблон_поиска_для3_переменных()
'
' Макрос3 Макрос
'
'
    Selection.Find.ClearFormatting
    With Selection.Find
        .Text = "партия"
        .Replacement.Text = ""
        .Forward = True
        .Wrap = wdFindContinue
        .Format = False
        .MatchCase = False
        .MatchWholeWord = False
        .MatchWildcards = False
        .MatchSoundsLike = False
        .MatchAllWordForms = False
    End With
    If Selection.Find.Execute Then
    Application.Run MacroName:="Макрос1для_партии"
    End If
    If Not Selection.Find.Execute Then
    Selection.Find.ClearFormatting
    Selection.Find.Replacement.ClearFormatting
    With Selection.Find
        .Text = "серийный"
        .Replacement.Text = ""
        .Forward = True
        .Wrap = wdFindContinue
        .Format = False
        .MatchCase = False
        .MatchWholeWord = False
        .MatchWildcards = False
        .MatchSoundsLike = False
        .MatchAllWordForms = False
    End With
    
    If Selection.Find.Execute Then
    Application.Run MacroName:="Макрос2_для_серийного"
      End If
      If not Selection.Find.Execute Then
      Selection.Find.ClearFormatting
    Selection.Find.Replacement.ClearFormatting
    With Selection.Find
        .Text = "еди"
        .Replacement.Text = ""
        .Forward = True
        .Wrap = wdFindContinue
        .Format = False
        .MatchCase = False
        .MatchWholeWord = False
        .MatchWildcards = False
        .MatchSoundsLike = False
        .MatchAllWordForms = False
    End With
   Selection.Find.Execute
    Selection.TypeText Text:="Третий вариант событий"
    If Not Selection.Find.Execute Then
      End If
      End If
      End If
        Selection.EndKey Unit:=wdStory
        Selection.TypeParagraph
        Selection.TypeText Text:="конец строки и общее продолжение макроса"
    Selection.TypeParagraph
    
End Sub
  • Remove From My Forums
  • Question

  • When I do a Selection.find using wildcards, it returns a number of corresponding words. Are those words automatically a Collection? I want to create a list of unique words found at the end of the document with no duplicates in the list (yes, I know that’s
    a tautology!) — would that require a dictionary function?

    • Edited by

      Thursday, February 6, 2014 1:52 PM

    • Moved by
      Jeffrey_Chen_
      Monday, February 10, 2014 5:52 AM
      word development question

Answers

  • Hi,

    Based on my understanding, Did you want get all of the unique words from a document and create list with these words.

    If so , you can just set wildcards to «?*[ |,|.|;|’|:|?]» like below:

    Sub Main()
    Dim List As New Collection
    Dim r As Range
    Set r = ActiveDocument.Range
    r.Select
    
    With Selection.Find
        .ClearFormatting
        .text = "?*[ |,|.|;|'|:|?]"
        .Forward = True
        .Wrap = wdFindStop
        .MatchWildcards = True
        .MatchCase = False
        .MatchWholeWord = False
        .MatchAllWordForms = False
        .MatchSoundsLike = False
        .MatchWildcards = True
    End With
    Do While Selection.Find.Execute
    
    Dim strResult As String
    strResult = Left(Selection.text, Len(Selection.text) - 1)
    
        If (Not IsContainValue(List, strResult)) Then
            List.Add (strResult)
        End If
    Loop
    
    End Sub
    
    Function IsContainValue(List As Collection, text As String) As Boolean
        For Each Item In List
            If (Item = text) Then
                IsContainValue = True
                Exit Function
            End If
        Next Item
        IsContainValue = False
    End Function
    

    This sample code can find all of words in document and save these to List collection.

    Regards,


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.

    Click
    HERE to participate the survey.

    • Marked as answer by
      sluice
      Tuesday, February 11, 2014 10:20 AM

Like this post? Please share to your friends:
  • Vba word добавить документ к документу
  • Vba word select from to
  • Vba word для начинающих
  • Vba word save file
  • Vba word диалог сохранения