none
Find.execute: Wie greife ich auf das Gefundene als Range zu? RRS feed

  • Frage

  • Moin,

    find.execute gibt true zurück, wenn der Suchbegriff gefunden wurde.
    Wenn ich ein range-Objekt verwende und die Methode darauf anwende: Wie bekomme ich nun Zugriff auf das gefundene Ziel, am liebsten als Range? (Um z.B. in einer Tabelle eine Zeile mit dem gefundenenen Begriff zu löschen, oder das Wort nach dem gefundenen zu finden)

    Samstag, 13. Februar 2016 11:32

Antworten

  • Die Parent Eigenschaft gibt Dir ein Object das das gefundene Range darstellt.
    D.h. definierst Du ein Range vorher  und benutzt dieses zum Suchen, dann verweist es nach Execute auf die Stelle.

    Andreas.

    Sub FindAndShow()
      Dim R As Range
      
      'Get the range for the whole document
      Set R = ActiveDocument.Content
      'Search for the keyword
      Do While R.Find.Execute("Label")
        'Note: Find.Execute modifies the object R to the location of the keyword!
        R.Select
        
        If MsgBox("Search for next occurence?", vbOKCancel) = vbCancel Then Exit Sub
        
        'Setup object R to the position after the keyword up to the end of the document
        R.SetRange R.End, ActiveDocument.Content.End
      Loop
    End Sub
    

    Samstag, 13. Februar 2016 12:38
  • Hmm, ist wohl ein blödes Beispiel... sehen kannst Du es im Watchfenster:

    Vor Execute:

    Nach Execute:

    Und das Parent:

    Sub temp()
       Dim act As Range, fnd As Range
       Dim ii As Long
       Set act = ActiveDocument.Range
       With act.Find
        .Wrap = wdFindStop
        Do While .Execute("wie")
           ii = ii + 1
           Debug.Print ii, act.Start, act.End
           Set fnd = .Parent
           Debug.Print ii, fnd.Start, fnd.End
           'act.Delete
        Loop
       End With
    End Sub
    

    Der Haken in meinem Beispiel war alle Vorkommen von "Label" durchzunummerieren. Wenn Du das mit Deiner Methode (ohne SetRange) probierst, dann landest Du in einer Endlos-Schleife:

    Sub FindReplace()
      Dim i As Integer
      Dim R As Range
      
      'Setup a scenario
      ActiveDocument.Content.Delete
      For i = 1 To 10
        Selection.TypeText "Label" & vbCrLf
      Next
      i = 0
      
      'Get the range for the whole document
      Set R = ActiveDocument.Content
      'Search for the keyword
      R.Find.Wrap = wdFindStop
      Do While R.Find.Execute("Label")
        'Note: Find.Execute modifies the object R to the location of the keyword!
        'Note: InsertAfter expand the object R to include the text to be inserted!
        
        'Insert the counter after the keyword
        i = i + 1
        R.InsertAfter " " & i
        'Setup object R to the position after the keyword up to the end of the document
        R.SetRange R.End, ActiveDocument.Content.End
      Loop
    End Sub

    Andreas.

    Samstag, 13. Februar 2016 13:58
  • Hallo Migration Sucks,

    um noch einmal auf Deine ursprünglich Frage zurückzukommen, wie Du Zugriff auf das gefundene Ziel bekommst.

    Das ist ganz einfach.

    Wenn Du die Suche aus einem Range Objekt startest, und ein Ergebnis findest, dann wird das Range Objekt auf das gefunden Ziel gesetzt:

    Dim rngFind As Range Set rngFind = ActiveDocument.Content rngFind.Find.Execute FindText:="Suchtext", Forward:=True If rngFind.Find.Found = True Then MsgBox (rngFind.Text)

    rngFind.Delete

    End If

    Wenn im gesamten Dokument der Text "Suchtext" gefunden wird, dann steht rngFind in meinem Beispiel auf dem gefundenen Text "Suchtext", und löscht diesen.

    Grüße

    Roland

    Samstag, 13. Februar 2016 14:05

Alle Antworten

  • Die Parent Eigenschaft gibt Dir ein Object das das gefundene Range darstellt.
    D.h. definierst Du ein Range vorher  und benutzt dieses zum Suchen, dann verweist es nach Execute auf die Stelle.

    Andreas.

    Sub FindAndShow()
      Dim R As Range
      
      'Get the range for the whole document
      Set R = ActiveDocument.Content
      'Search for the keyword
      Do While R.Find.Execute("Label")
        'Note: Find.Execute modifies the object R to the location of the keyword!
        R.Select
        
        If MsgBox("Search for next occurence?", vbOKCancel) = vbCancel Then Exit Sub
        
        'Setup object R to the position after the keyword up to the end of the document
        R.SetRange R.End, ActiveDocument.Content.End
      Loop
    End Sub
    

    Samstag, 13. Februar 2016 12:38
  •     'Note: Find.Execute modifies the object R to the location of the keyword!
       

    Das ist ja wirklich interessant. Aber auch verwirrend. Denn auch das funktioniert korrekt:

    Sub temp()
       Dim act As Range, fnd As Range
       Dim ii As Long
       Set act = ActiveDocument.Range
       Do While act.Find.Execute("wie")
          ii = ii + 1
          act.Delete
       Loop
       Debug.Print ii
    End Sub

    Ich kann also das gefundene range löschen, ohne das range des Gesamtdokumentes zu beeinflussen, obwohl es gleich bezeichnet ist. Ich muss das range auch nicht erweitern (wie Du es im code gemacht hast)
    Kannst Du mir das erklären, wie das im Speicher funktioniert?

    PS: das mit der .parent-Eigenschaft versteh ich nicht. Auf welches Range wird das angewandt?


    Samstag, 13. Februar 2016 13:29
  • Hmm, ist wohl ein blödes Beispiel... sehen kannst Du es im Watchfenster:

    Vor Execute:

    Nach Execute:

    Und das Parent:

    Sub temp()
       Dim act As Range, fnd As Range
       Dim ii As Long
       Set act = ActiveDocument.Range
       With act.Find
        .Wrap = wdFindStop
        Do While .Execute("wie")
           ii = ii + 1
           Debug.Print ii, act.Start, act.End
           Set fnd = .Parent
           Debug.Print ii, fnd.Start, fnd.End
           'act.Delete
        Loop
       End With
    End Sub
    

    Der Haken in meinem Beispiel war alle Vorkommen von "Label" durchzunummerieren. Wenn Du das mit Deiner Methode (ohne SetRange) probierst, dann landest Du in einer Endlos-Schleife:

    Sub FindReplace()
      Dim i As Integer
      Dim R As Range
      
      'Setup a scenario
      ActiveDocument.Content.Delete
      For i = 1 To 10
        Selection.TypeText "Label" & vbCrLf
      Next
      i = 0
      
      'Get the range for the whole document
      Set R = ActiveDocument.Content
      'Search for the keyword
      R.Find.Wrap = wdFindStop
      Do While R.Find.Execute("Label")
        'Note: Find.Execute modifies the object R to the location of the keyword!
        'Note: InsertAfter expand the object R to include the text to be inserted!
        
        'Insert the counter after the keyword
        i = i + 1
        R.InsertAfter " " & i
        'Setup object R to the position after the keyword up to the end of the document
        R.SetRange R.End, ActiveDocument.Content.End
      Loop
    End Sub

    Andreas.

    Samstag, 13. Februar 2016 13:58
  • Hallo Migration Sucks,

    um noch einmal auf Deine ursprünglich Frage zurückzukommen, wie Du Zugriff auf das gefundene Ziel bekommst.

    Das ist ganz einfach.

    Wenn Du die Suche aus einem Range Objekt startest, und ein Ergebnis findest, dann wird das Range Objekt auf das gefunden Ziel gesetzt:

    Dim rngFind As Range Set rngFind = ActiveDocument.Content rngFind.Find.Execute FindText:="Suchtext", Forward:=True If rngFind.Find.Found = True Then MsgBox (rngFind.Text)

    rngFind.Delete

    End If

    Wenn im gesamten Dokument der Text "Suchtext" gefunden wird, dann steht rngFind in meinem Beispiel auf dem gefundenen Text "Suchtext", und löscht diesen.

    Grüße

    Roland

    Samstag, 13. Februar 2016 14:05
  • :

    Vor Execute:

    Nach Execute:


    Das ist ja noch verwirrender: act.find hat schon "wie wie wie " drin, bevor  in der .execute-Methode das Suchwort festelegt wurde !!! ???
    Samstag, 13. Februar 2016 15:05
  • Das ist ja noch verwirrender: act.find hat schon "wie wie wie " drin, bevor  in der .execute-Methode das Suchwort festelegt wurde !!! ???

    Nee; nicht act.Find im Watch-Fenster siehst Du act vom Typ Range dessen Default Eigenschaft Text gibt den Wert "Wie  Wie    " zurück, und zwar nach dem Ausführen dieser Zeile:

    Set act = ActiveDocument.Range

    Weil ich "Wie" ENTER "Wie" ENTER in Word vorher geschrieben hatte.

    Entschuldigung für die Verwirrung, ich hab 'nen bißchen eine Erkältung. :-)

    Andreas.

    Samstag, 13. Februar 2016 18:06
  • Weil ich "Wie" ENTER "Wie" ENTER in Word vorher geschrieben hatte.

    Ach so. Alles klar.

    Gute Besserung!

    Sonntag, 14. Februar 2016 11:28
  • Ich kann also das gefundene range löschen, ohne das range des Gesamtdokumentes zu beeinflussen, obwohl es gleich bezeichnet ist. Ich muss das range auch nicht erweitern (wie Du es im code gemacht hast)
    Kannst Du mir das erklären, wie das im Speicher funktioniert?

    Die Erklärung muss so sein:
    Es wird durch das act.find.execute ein Find-Objekt erzeugt. Dieses enthält die erforderlichen Daten des act-Objektes. Danach wird durch das .execute das act-Objekt verändert, und zwar dauerhaft bei jedem neuen execute, die Informationen im Find-Objekt bleiben aber erhalten.

    Ausgeschrieben wäre das so:

    Sub temp()
       Dim act As Range
       Dim fiRg As Find
       Dim ii As Long
       
       Set act = ActiveDocument.Range
       Set fiRg = act.Find
       
       Do While fiRg.Execute("die")
          ii = ii + 1
          'act == fiRg.parent!
          act.Delete
       Loop
       Debug.Print
    End Sub

    Auch hier aber wieder eigenartig:
    Ein Einfügen von Text (siehe  Andreas' code) an das range act ändert offenbar wieder das range im find-objekt.

    Sonntag, 14. Februar 2016 11:51