Text in Fenster suchen/finden und anschließend den nachfolgenden Text in den Zwischenspeicher kopieren?

  • Hallo zusammen,

    ich habe mir mittlerweile ein paar Scripts zusammengeschrieben, die gut funktionieren.
    Wenn ich etwas nicht wusste oder nicht verstanden habe, bin ich bisher immer mit Googlen ans Ziel gekommen.
    Nun ist aber Schicht im Schacht, ich komme einfach nicht weiter...
    Daher habe ich mich nun angemeldet und hoffe auf eure Hilfe :thumbup:

    Es geht darum: Ich habe im "Visible Text" eines Fensters immer an der gleichen Stelle einen Wert, welcher sich jedoch verändert:

    Spoiler anzeigen


    ...
    &Versenden
    abc
    def
    ...
    &Parameter
    ghi
    ...
    &Adresse
    713018
    183422
    ...

    Es geht immer um die Nummer hinter "&Adresse". Wie gesagt, die Nummer verändert sich.
    Meine Idee war also, dass das Script erst mal den "Visible Text" nach "&Adresse" durchsucht und anschließend eine Zeile runter geht und dann die Zeile in den Zwischenspeicher kopiert.
    Diesen Wert muss ich anschließend nämlich wo anders wieder einfügen.

    Habt ihr dazu eine Lösung?
    Oder denke ich zu umständlich und es geht auch einfacher?
    :rolleyes:

    Falls ihr noch weitere Infos benötigt, lasst es mich wissen.
    Danke schon mal im Voraus :)

    Grüße
    Padde

    Einmal editiert, zuletzt von Padde86 (7. Oktober 2015 um 14:12)

  • Wenn du den Teil mit dem Auslesen des ganzen "Visible Texts" schon geschafft hast, ist der Rest nur noch String-Schnippelei. Grundsätzlich zwei Möglichkeiten:
    1. Händisch den Text mit allen möglichen String-Funktionen zerlegen, bis du deine Nummer hast. Ist für Anfänger leichter zu verstehen, bedeutet jedoch Aufwand und Bastelei.
    2. StringRegExp nutzen. Ist deutlich schwerer zu verstehen, geht allerdings, wenn man es einmal kann, wesentlich schneller und einfacher. Außerdem ist es eleganter.

    Ich habe mal die zweite Möglichkeit schnell aus dem Kopf heraus umgesetzt.

    Code
    Func GetNumber($sWholeText)
    	Return StringRegExp($sWholeText, "(?m)^\Q&Adresse\E\n(.+)$", 3)[0]
    EndFunc

    Ohne Errorhandling usw... Aber das Pattern sollte stimmen.

    Erklärung des Pattern

    Das heißt, unser Ergebnis ist das, was in den runden Klammern steht. Wir schauen halt, welche Rahmenbedingungen dieser Text erfüllen muss.

    Edit:
    Mir dämmert gerade, dass es mit \n als Zeilenumbruch unter Windows nicht getan ist. Einfach durch ein \s* ersetzen, dann sollte auch das gehen. Hat den Hintergrund, dass Windows anders als Linux die Sequenz \r \n (Carriage Return & Line Feed, CRLF) zum Zeilenumbruch nutzt. Ich bin jetzt von Linux ausgegangen, da ist es nur \n. \s matcht alle nicht-sichtbaren Zeichen, * steht für beliebige Anzahl.
    Neues Pattern:

    Code
    (?m)^\Q&Adresse\E\s*(.+)$
  • Hallo chesstiger,

    erst einmal VIELEN DANK für deine Antwort :thumbup:

    Ich gehe davon aus, dass es dann ungefähr so aussehen müsste:

    AutoIt
    WinGetText("Mein Fenster", "")
    Func GetNumber($sWholeText)
    Return StringRegExp($sWholeText, "(?m)^\Q&Adresse\E\n(.+)$", 3)[0]
    EndFunc
    
    
    run("notepad.exe")
    sleep(2000)
    send("{CTRLDOWN}v{CTRLUP}")

    Das hat den String dann aber noch nicht kopiert und fügt mir somit nichts (oder was altes aus der Zwischenablage) ein.
    Kannst du mir bitte noch soweit auf die Sprünge helfen, dass es noch in den Zwischenspeicher kopiert? :rolleyes:

    Danke nochmal und Grüße
    Padde

  • Uah. Kann es sein, dass dir noch ein paar... Grundkenntnisse fehlen? :D

    Du musst das Ergebnis von WinGetText in einer Variable speichern. Wie im Schulunterricht bei einem x=5, nur dass du hier einfach sowas wie $sText = WinGetText(...) schreibst. Dann kannst du mit dieser Variable weiterarbeiten. Ich habe dir eine Funktion geschrieben. Wenn wir unsere Analogie mit dem Schulunterricht weiterführen, hast du hier eine Funktion wie f(x). Das heißt, du musst in die Klammern als Argument das Ergebnis von WinGetText (=>$sText) einfügen. Das ganze speichern wir wieder: $sSearch = GetNumber($sText). Zum Schluss nutzen wir mit unserem Ergebnis noch die ClipPut-Funktion. Damit schmeißen wir etwas in die Zwischenablage: ClipPut($sSearch).
    Du kannst hier ein Grundlagentutorial als PDF runterladen. Diese kurze Erklärung kann das nämlich nicht ersetzen. ^^

    Guck nochmal in meinem ersten Post, ich habe da noch was geändert.

  • Hallo chesstiger,

    möglicherweise fehlen noch ein paar Grundkenntnisse, ja :D

    Ich habe mir bisher halt ein Script gemacht, welches den Autostart meines PC im Geschäft automatisiert.
    Also Öffne Programm A -> warte bis aktiv -> minimiere -> öffne Programm B -> etc...

    Nun bin ich dabei, weitere Abläufe zu "vereinfachen". Zusammen mit AutoHotKey gehen manche Dinge so mit einem Knopfdruck, anstatt mit vielen Klicks und manuellem Schreiben :)
    Also die "GRUND-Grundkenntnisse" sind schon da :P

    Unser Programm hat jedoch ein Fenster, in welches man nicht reinklicken kann.
    Daher benötige ich die sechsstellige Nummer aus dem "Visible Text".
    So weit sind meine Kenntnisse nun aber noch nicht, wie man ja sieht und merkt 8)

    Leider pressiert es etwas.
    Ich verspreche hoch und heilig, dass ich mir die PDF nachher (und in den folgenden Tagen) zu Gemüte führe.
    Habe gerade schon reingeschaut, siehe auf jeden Fall interessant aus!

    Darf ich dennoch höflich darum betteln, dass du es mit kurz hinzauberst?
    Nicht, weil ich zu faul bin, sondern weil es ein kleines bisschen eilt.

    So sieht es bei mir aktuell aus (und funktioniert natürlich nicht):

    AutoIt
    $sText = WinGetText("Mein Fenster", "")
    Func GetNumber($sWholeText)
    	Return StringRegExp($sWholeText, "(?m)^\Q&Adresse\E\s*(.+)$", 3)[0]
    $sSearch = GetNumber($sText)
    ClipPut($sSearch)
    EndFunc
    run("notepad.exe")
    sleep(2000)
    send("{CTRLDOWN}v{CTRLUP}")

    Danke für deine Hilfe und auch für die nette Art und Weise, in der du es mir erklärst.
    Nicht nur so "schau hier, schau dort" - wirklich ernst gemeint -> DANKE! :klatschen:

    PS: Deine Änderung im ersten Post habe ich gesehen und berücksichtigt :thumbup:

    Grüße
    Padde

  • AH ICH HABE ES !!!

    Ein bisschen in der PDF weitergelesen und verstanden !!!!

    AutoIt
    $sText = WinGetText("Mein Fenster", "")
    Func GetNumber($sText)
    	Return StringRegExp($sText, "(?m)^\Q&Adresse\E\s*(.+)$", 3)[0]
    EndFunc
    $sSearch = GetNumber($sText)
    ClipPut($sSearch)
    run("notepad.exe")
    sleep(2000)
    send("{CTRLDOWN}v{CTRLUP}")

    JUHU, DANKE !!!

    <3:klatschen::party:<3

  • So im allgemeinen: Meistens schreibt man die Funktionen nach ganz unten, da die ja überall aufgerufen werden können, ist dann etwas übersichtlicher :)
    Demnach dann so:

    Bei dem kleinen Programm hier aber eher nicht von Bedeutung :)

  • So, nächstes großes Fragezeichen im Gesicht...

    Ich möchte nun nach einem anderen Wert suchen, dafür benötige ich ab "Beleg gedruckt" sieben Zeilenumbrüche!

    Müsste das dann irgendwie so aussehen?

    AutoIt
    Return StringRegExp($sTextOrder, "(?m)^\QBeleg gedruckt\E\s\s\s\s\s\s\s(.+)$", 3)[0]

    Oder so?


    AutoIt
    Return StringRegExp($sTextOrder, "(?m)^\QBeleg gedruckt\E\s{7}(.+)$", 3)[0]

    Aus welchen Gründe auch immer tun beide nicht :(

    Danke & Grüße
    Padde

  • \s* ist ja nur der Zeilenumbruch und etwaige Leerzeichen an sich. Da fehlt noch der Inhalt jeder Zeile. Wir können verallgemeinernd sagen, dass jede Zeile aus einem Haufen Zeichen und dem Zeilenumbruch am Ende besteht. Eine Zeile erfassen wir also mit .*\s*, sprich "Eine beliebige Anzahl von Zeichen und dann eine beliebige Anzahl von Whitespaces (Zeilenumbruch)". Das packen wir in eine sogenannte Non-Capturing Group ((?:...)). Das ist eine Gruppe (also etwas, was durch runde Klammern begrenzt wird), deren Ergebnis aber nicht gespeichert wird. So können wir einen Multiplikator {n} auf den gesamten Ausdruck .*\s* anwenden: (?:.*\s*){n}
    Das müssen wir jetzt nur noch richtig in unserem vorherigen Pattern ((?m)^\Q&Adresse\E\s*(.+)$) einfügen. Nur wo? Nun, der Teil für die erste Zeile und den Zeilenumbruch danach muss so im ganzen bestehen bleiben, der Teil für das eigentliche Festhalten des Suchtextes auch. Also schreiben wir unser Code-Fragment dazwischen. Jetzt gilt es nur noch, den Multiplikator richtig zu wählen. Da wir schon einen Zeilenumbruch nach der ersten Zeile finden, müssen wir hier nur noch den Multiplikator 6 wählen: (?m)^\Q&Adresse\E\s*(?:.*\s*){6}(.+)$
    Zu guter letzt muss natürlich noch das &Adresse ersetzt werden: (?m)^\QBeleg gedruckt\E\s*(?:.*\s*){6}(.+)$


    Testweise hat es so funktioniert. Wenn nicht, melde dich. ^^

  • Weil chess dich hier mit RegEx erschlägt geb ich dir das mal mit Splitten, dann kannst du es auch einfacher selbst probieren^^

    Falls du was nicht verstehst, einmal ausführen und dir das Array einmal ansehen. Sonst gerne noch Fragen.
    Das RegEx, was Chesstiger benutzt ist meiner Meinung nach für so eine simple Aufgabe eigentlich nicht nötig^^, aber wenn mans kann ist gut :)

    MfG Kanashius

  • Man gewöhnt es sich lieber schon früh an. Natürlich, es geht auch anders... Aber RegExp ist einfach einen ganzen Tacken schneller, sowohl beim Schreiben als auch beim Ausführen. :P

    Vergleich


    Und er hat ja schon einen Teil von RegExp verstanden, sieht man ja an den (guten) Versuchen.

  • Hallo Kanashius und chesstiger,

    haha unfassbar mit AutoIt kann man sogar Benchmarks laufen lassen, welche Funktion schneller ist!? Wahnsinn! :D

    Ich möchte mich natürlich auf jeden Fall bei euch beiden bedanken, dass ihr euch das angeschaut und euch die Zeit genommen habt, euch damit auseinanderzusetzen! :klatschen:

    Kanashius hat weiter oben geschrieben, dass es sich um ein "kleines Programm" handelt.
    So klein ist es aber gar nicht - mein eines Script hat 46 Zeilen und das andere 104 Zeilen.
    Gut, für eure Verhältnisse ist das wahrscheinlich WINZIG 8)

    Da ich immer am weiter Schreiben bin, werden sich mir sicherlich noch ein paar Fragen stellen.
    Wer Interesse am Code hat, dem schicke ich ihn gerne mal im Ganzen.
    Da hier aber geschäftliche Infos lesbar sind, möchte ich ihn nicht öffentlich posten - ich gehe davon aus, dass Ihr Verständnis dafür habt. =O

    Ich verbleibe demütig und dankbar :thumbup:

    Grüße
    Padde

  • Hallo,

    ich mal wieder :)

    Frage:

    AutoIt
    Func GetAnsprechpartner($sText)
    	Return StringRegExp($sText, "(?m)^\Test Test Test\E\s*(?:.*\s*){10}(.+)$", 3)[0]
     EndFunc

    Dieser Funktion sucht ja ab "Test Test Test" in der 11ten Zeile (nach unten).
    Wie kann man das umbiegen, dass er von dort aus "nach oben" sucht?
    Ich hoffe, ihr versteht :)

    Danke im Voraus.

    Grüße
    Padde

  • Und hier die Lösung, für das Script, das ich oben schon genutzt hatte. (Leider ungetestet, bin in der Uni->Linux Laptop)

    Ist vielleicht ein bisschen mehr Quellcode, ich denke, dass du die Änderungen aber entsprechend selber hättest machen können, da es verständlicher ist.

    MfG Kanashius.

  • Ich bräuchte wirklich nur die Funktion, dass er eine Zeile oberhalb von (z.B.) "EUR" sucht.

    Geht irgendwas in diese Richtung hier?

    AutoIt
    Func GetAnsprechpartner1($sText)
    	Return StringRegExp($sText, "(?m)^\QEUR\E\s*(?:.*\s*){-1}(.+)$", 3)[0]
     EndFunc

    Ich habe "-1" eingesetzt. Das funktioniert NICHT!
    Aber gibt es eine Möglichkeit in dieser Richtung?

    :)

  • ka worums grade geht, aber eine zeile oberhalb von "x":


    :D

    Simon nörgelt, Simon nervt - aber Simon verbessert die Welt. Glaubt er.

  • Hallo x0r, und danke!

    Return StringRegExp($sText, "(?m)^\QEUR\E\s*(?:.*\s*){1}(.+)$", 3)[0]

    Das fett markierte ist doch ein "Quantifier", oder?
    Lassen sich keine negative Quantifier benutzen? :(

  • Lassen sich keine negative Quantifier benutzen?

    Du hast die Funktion der Regular Expressions nicht verstanden...
    Wieso lässt du dir nicht einfach die Zeile VOR dem EUR ausgeben anstatt die danach?


    AutoIt
    $text="bla" & @crlf&"blub"& @crlf&"test"& @crlf& "tralala EUR..." & @crlf& "ende"&@crlf
    
    
    $ret=StringRegExp($text, "(?m)(^.+$)\r\n(?:^.+EUR.+)", 3)  
    
    
    msgbox(0,0,$text & @crlf & $ret[0])

    (?m) multiline, ^und $ sind Anfang und Ende der Zeile
    (^.+$) ^Zeilenanfang .+ eins oder mehr Zeichen $ Zeilenende in Klammern ist dein MATCH!!!
    \r\n CR und LF
    (?: nicht matchende Gruppe
    ^.+EUR.+) Zeileninhalt enthält EUR

    der Match enthält die Zeile, welche VOR der Zeile mit EUR steht