marcoborn
Goto Top

String-Vergleich optimieren

Hallo Forum,
ich habe folgenden Code-Schnipsel (vereinfacht):
With mObjWordApplication
  For intI As Integer = 1 To .Paragraphs.Count
    If InStr(.Paragraphs(intI).Range.Text, mObjDOKRM.GetString("String456", DOKCulture), CompareMethod.Text) > 0 OrElse  
    InStr(.Paragraphs(intI).Range.Text, mObjDOKRM.GetString("String434", DOKCulture), CompareMethod.Text) > 0 OrElse  
    InStr(.Paragraphs(intI).Range.Text, mObjDOKRM.GetString("String457", DOKCulture), CompareMethod.Text) > 0 OrElse  
    InStr(.Paragraphs(intI).Range.Text, mObjDOKRM.GetString("String433", DOKCulture), CompareMethod.Text) > 0 OrElse  
    InStr(.Paragraphs(intI).Range.Text, mObjDOKRM.GetString("String436", DOKCulture), CompareMethod.Text) > 0 OrElse  
    InStr(.Paragraphs(intI).Range.Text, mObjDOKRM.GetString("String439", DOKCulture), CompareMethod.Text) > 0 OrElse  
    InStr(.Paragraphs(intI).Range.Text, mObjDOKRM.GetString("String437", DOKCulture), CompareMethod.Text) > 0 OrElse  
    InStr(.Paragraphs(intI).Range.Text, mObjDOKRM.GetString("String438", DOKCulture), CompareMethod.Text) > 0 OrElse  
    InStr(.Paragraphs(intI).Range.Text, mObjDOKRM.GetString("String435", DOKCulture), CompareMethod.Text) > 0 Then  
      ....
    End If
  Next
End With

Ich vergleiche für jeden Absatz eines Word-Textes Inhalte mit 9 Strings, die ich in einer Ressourcen-Tabelle abgelegt habe. Ein Teil der Absätze enthält jeweils einen der gesuchten Strings. Bei der u.U. sehr großen Word-Dateien dauert das ziemlich lange.

Wie kann ich diese If-Then-Else-Verschachtelungen optimieren, so dass ich hier einen Performancegewinn erzielen kann? Ginge sowas ggf. mit einer RegEx?

Vielen Dank,
M. Born

Content-ID: 472514

Url: https://administrator.de/contentid/472514

Ausgedruckt am: 21.11.2024 um 21:11 Uhr

emeriks
Lösung emeriks 12.07.2019 aktualisiert um 10:21:15 Uhr
Goto Top
Hi,
zumindest kannst Du den Code drastisch vereinfachen. (lesbarer gestalten)
Ob das dann schneller ist, muss man testen.

With mObjWordApplication
    Dim IC = StringComparer.CurrentCultureIgnoreCase
  For intI As Integer = 1 To .Paragraphs.Count
     Dim Text as string = .Paragraphs(intI).Range.Text
     If Text.Contains(mObjDOKRM.GetString("String456", DOKCulture), IC) OrElse  
         Text.Contains(mObjDOKRM.GetString("String434", DOKCulture), IC) OrElse _  
         ........  Then
      ....
    End If
  Next
End With

Oder weiter
With mObjWordApplication
  For intI As Integer = 1 To .Paragraphs.Count
     Dim Text as string = .Paragraphs(intI).Range.Text
     Dim GetStringFound as boolean = False
     For Each GetString  In {"String456", "String434", "String457", "String433",......}  
        GetStringFound = Text.Contains(mObjDOKRM.GetString(GetString, DOKCulture), StringComparer.CurrentCultureIgnoreCase)
        If GetStringFound Then Exit For
     Next
    If GetStringFound Then
      ....
    End If
  Next
End With


E.
MarcoBorn
MarcoBorn 12.07.2019 um 10:23:25 Uhr
Goto Top
Vielen Dank. Den StringComparer kannte ich noch nicht.
colinardo
Lösung colinardo 12.07.2019 aktualisiert um 11:58:35 Uhr
Goto Top
Servus.
Oder man nutzt gleich die im Word Object integrierte Suche mit dem Array aus Suchbegriffen in einer Schleife, das liefert auch gleich den Range mit wo die Fundstelle erfolgreich war:
https://docs.microsoft.com/de-de/office/vba/api/word.find.execute
Das eliminiert die langsame Schleife über alle Absätze.

Oder eben mit Regex auch kein Problem
Dim arrSearchTerms As String() = {"String456", "String443"}  
Dim arrEscaped = arrSearchTerms.Select(Function(str) System.Text.RegularExpressions.Regex.Escape(str))
Dim strPattern As String = String.Join("|", arrEscaped)  

With mObjWordApplication
    For intI As Integer = 1 To .Paragraphs.Count
        If System.Text.RegularExpressions.Regex.IsMatch(.Paragraphs(intI).Range.Text, strPattern) Then
            '....  
        End If
    Next
End With

Grüße Uwe
MarcoBorn
MarcoBorn 12.07.2019 um 13:09:00 Uhr
Goto Top
Hallo Uwe,
auch danke für Deinen Code. Im Vergleich zu meinem bisherigen konnte ich die Durchlaufzeit auf ca. 1/3 reduzieren.

Schönes Wochenende,
M. Born