Viele StringReplace über ein und dasselbe Inputfenster laufen lassen

  • Moin AutoIT'ler,

    ich versuche momentan ein Tool für unsere Mitarbeiter zu entwickeln, was einen Quelltext ausliest und dort bestimmte Begriffe austauscht und in einem neuen Fenster als Zieltext ausgibt.

    Momentan ist es so, das ich nach jedem StringReplace die Box mit GUICtrlRead wieder neu auslese, wieder den weiteren Begriff suche und wieder ersetze. Bei z.B. 30 Begriffen die gesucht und evtl ersetzt werden müssen wären das mit meiner "Noob"-Variante ja unmengen an Code.

    Dass muss doch auch besser gehen.

    Ich poste hier mal das testskript:

    Spoiler anzeigen

    Im Text sollen also Begriff wie IP, IE, IPF, IEF und so weiter und so fort, gesucht und ersetzt werden. Also die Abkürzungen zum Beispiel sollen die vollständigen Wörter ausgeben. Bisher sieht man ja, dass ich jedesmal nach einem Replace die Box neu auslesen lasse...

    Das muss doch auch anders gehen...?

    LG
    Mirko

    Mein AutoIT Smartphone GUI >>hier<<

    Der Mensch ist das einzige Tier, dass arbeiten muss.

  • Hi,
    ja, das geht anders...

    Stelle uns einen Text zur Verfügung mit dem man "spielen" kann, und eine Liste (Datei) mit den Suchbegriffen und den entsprechenden Ersetzungen.
    Ich würde eine Datei, da simpel erweiterbar, in der Form von
    IP|International Priority
    IEF|International Economy Freight
    IPF|International Priority Freight
    empfehlen, diese Datei wird eingelesen und Zeilenweise auf den Text "losgelassen"...

    Übrigens kannst du dir sämtliche Abfragen nach nicht vorhandenen oder "falschen" Anreden sparen, wenn du eine der drei vorhandenen Anreden vorbelegst.

    Immer wiederkehrende Programmteile lagert man in eine Funktion() aus, damit verkürzt sich der Code massiv. und die Schreibarbeit/Wartbarkeit und Fehleranfälligkeit sinkt rapide.

  • Hallo Andy,

    also hier mal ein Text wie er aus einem unserer Programme rauskopiert wird. Daraus wird unserem Kunden ein Preisangebot per Mail erstellt. Einige Dinge habe ich gegen Dummywerte ausgetauscht, aus Datenschutzgründen (da Kundendaten).

    So sieht die Rohdatei aus:

    Spoiler anzeigen


    Detailed Commit: FRI 08/07/2015 20:00
    Bill To: S
    Term: P
    Rate for Account Nbr: 123456789
    Interline Account:
    Ship Date: 07/30/2015
    Device Type: Air Waybill
    Origin Country: DE
    Origin Postal Code: 29525
    Origin St/Prov: NS
    Origin City: UELZEN
    Origin Service Area: H2
    Origin OPCO: ABC
    Origin LOC Id: FRART
    Destination Country: ES
    Destination Postal Code: 08360 (08360)
    Destination St/Prov:
    Destination City: CANET DE MAR
    Destination Service Area: H2
    Destination OPCO: ABC
    Destination LOC Id: BCNRT
    Rate Zone: DE001O
    Number of Packages: 1
    Total Package Weight: 60.00 KG
    Customs Value: 1
    Customs Val. Currency Cd: EUR
    Service Type: INTERNATIONAL_ECONOMY_FREIGHT(86)
    Received At Code: Pick-up
    Commodity: MACHINERY, ELEC.
    Documentation: INTERNATIONAL_AIRWAY_BILL, COMMERCIAL_INVOICE
    Rate Currency Cd: EUR

    Line: #Pcs: Each: Weight: L: W: H: Packaging: Special Handling:
    1 1 false 60.00 KG 200 CM 40 CM 40 CM YOUR_PACKAGING(1)

    Details:
    Description Amount/InformationDiscount/Surcharge %
    Full Rate
    FREIGHT 244.80 EUR
    Net Rate 326.27
    Additional Charges:
    On call pickup 0.00
    Fuel Surcharge-12.0% 29.38
    Germany value-added 52.09
    Additional Information:
    Dimensional Weight Applied Not Applied
    OneRate - Applied Not Applied
    Dimensional Weight Applied Not Applied
    Pick Up
    Customs on Fixed Fuel Program? No
    Rate Type HW Actual
    Deficit Weight
    Rated as 68.0 KG

    Daraus wird bei uns über tausend Umwege ne ordentliche Mail generiert ala:

    Zitat

    Sehr geehrte Damen und Herren,


    wie gewünscht heir Ihr Preisangebot:

    ...
    ....
    ...

    Mit freundlichen Grüssen


    Und so weiter und so fort. Aus dem Roh-Kauderwelsch, muss also was ordentliches her. Entweder müssen Abkürzungen oder ganze Teile aus dem Rohformat gegen was "ordentliches" getauscht werden. Da stosse ich mit meinen Kentnissen an meine Grenze und weiss nicht mehr weiter. StringReplace hat mit meinem Wissen mir nur begrenzt geholfen :(

    Das mit der Anrede auswählen ist bewusst so gemacht, da bei einer Vorauswahl es passieren kann, dass der Mitarbeiter den "Punkt" übersieht und dann die falsche Anrede drin lässt, die als Default gewählt wurde. So ist es mir lieber, da der Mitarbeiter gezwungen ist eine Anrede auszuwählen, wenn er es übersieht.

    Gruss
    Mirko

    Mein AutoIT Smartphone GUI >>hier<<

    Der Mensch ist das einzige Tier, dass arbeiten muss.

    Einmal editiert, zuletzt von mirko2002 (4. August 2015 um 10:24)

  • Du möchtest also in einer Vorlage Platzhalter mit den entsprechenden Werten ersetzen?
    Markiere dafür die entsprechenden Stellen in der Vorlage z.B. durch Einschluss in Prozentzeichen oder ähnliches.
    Halt irgendwas, womit die Platzhalter schnell und einfach verarbeitet werden können.
    Dann lass diese mit den Werten aus der Datendatei ersetzen.

    Hier mal ein kleines Beispiel (die zugehörigen Dateien liegen im Anhang):

  • Hm Dein Beispiel endet bei mir nur in etlichen Fehlercodes:


    Mein AutoIT Smartphone GUI >>hier<<

    Der Mensch ist das einzige Tier, dass arbeiten muss.

  • Hi zusammen,

    das Thema ist für auch sehr spannend - letztlich ist das ja so eine Art Serienbrief unter Autoit.
    Das würde prima für unsere Info Letters passen.

    Im Übrigen bekomme ich das Script (fehlerfrei) zu Laufen, wenn in Aspirin Junkies Srcipt in Zeile 6 ein Hochkomma am Ende nachdem Stern und vor dem letzten Komma hinzugefügt wird.
    Allerings funktioniert die Ersetzung nicht - soll heissen die Platzhalter %....% werden nicht durch die im Dictionary eingelesenen Ausdrücke ersetzt.
    Wobei ich sagen muss, dass mir der zum Einlesen genutzte RegEx String nicht so ganz klar ist .....

    Spoiler anzeigen


    For $Match in StringRegExp(FileRead($sVARIABLEFILTEPATH), '(?m)^(.+?)\h*:\h*(.*?)\h*',4)


    mfg
    ugt100

  • Ok ja in der Tat, jetzt funktioniert das Beispiel.

    Ich bin grad durch die Hitze etwas überfordert (unklimatisiertes Büro hier :( )

    Das Beispiel verstehe ich - lässt es sich soweit auf folgendes Scenario übertragen?


    Also hier nochmal kurz in beidem zusammen der Roh-Text und der Ziel-Text der daraus erstellt werden muss:

    Rohtext:

    Spoiler anzeigen


    Detailed Commit: FRI 07/03/2015 18:00
    Bill To: S
    Term: P
    Rate for Account Nbr: 123456789 - FXE
    Interline Account:
    Ship Date: 07/01/2015
    Device Type: Air Waybill
    Origin Country: DE
    Origin Postal Code: 36037
    Origin St/Prov: HE
    Origin City: FULDA
    Origin Service Area: PM
    Origin OPCO: FXE
    Origin LOC Id: ZOQF
    Destination Country: AT
    Destination Postal Code: 5061
    Destination St/Prov: SB
    Destination City: SALZBURG
    Destination Service Area:
    Destination OPCO: FXE
    Destination LOC Id: SZGA
    Rate Zone: DE001O
    Number of Packages: 1
    Total Package Weight: 10.00 KG
    Customs Value: 1
    Customs Val. Currency Cd: EUR
    FedEx Service Type: INTERNATIONAL_ECONOMY(4)
    Received At Code: Pick-up
    Commodity: PLASTIC PARTS
    Documentation: INTERNATIONAL_AIRWAY_BILL, COMMERCIAL_INVOICE
    Rate Currency Cd: EUR

    Line: #Pcs: Each: Weight: L: W: H: Packaging: Special Handling:
    1 1 false 10.00 KG CM CM CM YOUR_PACKAGING(1)

    Details:
    Description Amount/InformationDiscount/Surcharge %

    Full Rate
    FREIGHT 31.50 EUR

    Net Rate 41.79

    Additional Charges:
    On call pickup 0.00
    Fuel Surcharge-11.5% 3.62
    Germany value-added 6.67


    Additional Information:
    Dimensional Weight Applied Not Applied
    OneRate - Applied Not Applied
    Dimensional Weight Applied Not Applied
    Pick Up
    Customs on Fixed Fuel Program? No
    Rate Type Actual
    Deficit Weight

    Rated as 10.0 KG

    Ziel-Text:

    Spoiler anzeigen


    Sehr geehrter Herr Test,

    vielen Dank für Ihre Anfrage.

    Die Transportkosten für Ihre Sendung von DE-36037 FULDA nach AT-5061 SALZBURG betragen 41.79 EUR inkl. Treibstoffzuschlag (3.62 EUR) und Mehrwertsteuer (6.67 EUR).

    Der Preis wurde anhand Ihrer folgenden Angaben berechnet:
    Versanddatum der Berechnung: 01.07.2015
    Serviceart: International Economy
    Verpackung: eigene
    Anzahl der Pakete: 1
    Abmessungen: 1 Paket mit CMxCMx (10 KG/Paket)
    Inhalt: PLASTIC PARTS
    Gesamtgewicht: 10 KG
    Volumengewicht: trifft nicht zu
    Transportversicherung: nein
    Versicherungswert: 0.00 EUR
    FedEx Kundennummer: 123456789 / Business
    Rate angefragt durch: Herr Test/ Tel: 030 666 666 666

    Bitte beachten Sie, dass bei kundeneigener Verpackung unbedingt die genauen Abmessungen verfügbar sein müssen, da sich eventuell ein Volumengewicht berechnet, das höher ist als das tatsächliche Gewicht. Bei Importen kann die angegebene Frachtrate Wechselkursschwankungen unterliegen. Der Treibstoffzuschlag wird monatlich festgelegt und kann –insbesondere wenn die Sendung erst zu einem späteren Zeitpunkt verschickt wird– differieren.

    Die Laufzeit beträgt 2 Werktage (Zustellung am 03.07.2015) sofern es keine Zollverzögerungen oder Unregelmäßigkeiten die außerhalb des Einflussbereiches von FedEx liegen gibt.

    Haben Sie regelmäßigen Versand? Wünschen Sie ein individuelles Angebot? Dann kontaktieren Sie bitte Ihren persönlichen Vertriebsansprechpartner, Herrn Mustermann unter Tel.: 0123456789!

    Mit freundlichen Grüßen

    Lässt sich so ein Text 1:1 umsetzen? Die Sätze im Zieltext sind auch immer Variabel. Der erste Satz im Beispiel lautet ja:

    Die Transportkosten für Ihre Sendung von DE-36037 FULDA nach AT-5061 SALZBURG betragen 41.79 EUR inkl. Treibstoffzuschlag (3.62 EUR) und Mehrwertsteuer (6.67 EUR).

    Dieser Satz ist Variabel. Es kann sein, dass mal die Mehrwertsteuer wegfällt, oder aber auch auf einmal ein Gefahrgutzuschlag auftaucht.

    Die Hitze macht mich grad echt fertig und ich bin zum denken nicht zu gebrauchen :(

    Mein AutoIT Smartphone GUI >>hier<<

    Der Mensch ist das einzige Tier, dass arbeiten muss.

  • Wobei ich sagen muss, dass mir der zum Einlesen genutzte RegEx String nicht so ganz klar ist .....

    • (?m) - damit ^ und $ Zeilenumbrüche statt Stringanfang/Ende finden
    • ^ - Zeilenanfang
    • (.+?) - irgendwelche Zeichen (davon aber so wenig wie möglich) = Der Variablenname vor dem Doppelpunkt
    • \h* - Optional eine unbestimmte Menge an horizontalen Leerzeichen (damit diese nicht Teil des gefundenen Variablennamens werden)
    • : - tja ein Doppelpunkt halt
    • \h* - Optional eine unbestimmte Menge an horizontalen Leerzeichen (damit diese nicht Teil des gefundenen Variablenwertes werden)
    • (.*?) - Der Variablenwert (also grob das was nach dem Doppelpunkt kommt)
    • \h* - Optional eine unbestimmte Menge an horizontalen Leerzeichen (damit diese nicht Teil des gefundenen Variablenwertes werden)
    • $ - Das Zeilenende
  • Lässt sich so ein Text 1:1 umsetzen?

    Im Prinzip ja.
    In deinem Fall musst du aber noch die ganzen Sonderfälle behandeln.
    Du musst prinzipiell aus der Eingabedatei aus allen Informationen eine Name-Wert-Beziehung machen.
    Bei den oberen Werten ist es einfach denn dort ist das Schema ja Name:Wert.
    Bei den Werten darunter ist das dann nicht mehr der Fall.
    Entweder du schaffst es darin ein Schema zu erkennen und für die Verarbeitung auszunutzen oder du fragst explizit diese Sonderfälle gesondert ab. (z.B. suchst du direkt nach "Net Rate " und übernimmst den Wert dahinter usw.).
    Wenn du die Werte dann alle im Dictionary hast, musst du manche Rohwerte noch in die Zielform bringen.
    Z.B. das Ship-Date von der englischen in die deutsche Notation zu konvertieren usw.

    Allgemeingültig gibt es für dein Beispiel also keine direkte Lösung - du musst die Sonderfälle direkt behandeln.

  • Ja genau vor dem Problem stehe ich nämlich gerade... probiere mich gerade an Deinem Beispiel etwas rum und ich muss unter anderem das von dir angesprochene Datum konvertieren und auch aus den Begriffen wie INTERNATIONAL_ECONOMY(4) muss ja ein "International Economy" draus werden. Also die Zielmails sind alle gleich. Nur "ein paar" Variablen ändern sich immer und darum geht es. Rauszufionden welche Variablen gerade da sind für die Mail und diese einzusetzen/ersetzen.

    Mein AutoIT Smartphone GUI >>hier<<

    Der Mensch ist das einzige Tier, dass arbeiten muss.

  • Ok super, Datum konnte ich schon konvertieren lassen mit dem Tipp, auch die Serviceart wird durch ein extra Replace vor der Ausgabe konvertiert.

    Nun hab ich aber noch das Problem, sobald bestimmte Begriffe die ich suche, nicht mit Doppelpunkt enden, findet er sie natürlich nicht.

    Als Beispiel:

    Service Type: INTERNATIONAL_ECONOMY - findet er
    Net Rate 90€ - findet er nicht

    Soweit ich es gesehen habe wird das ja über diese Zeile realisiert:

    AutoIt
    For $Match in StringRegExp(FileRead($sVARIABLEFILTEPATH), "(?m)^(.+?)\h*:\h*(.*?)\h*$", 4)

    Wie müsste diese Zeile lauten, damit ich auch Begriffe wie dieses "Net Rate" oder ähnliches suchen kann?

    Das ganze ist nicht sooo einfach wie ich es mir "erhofft" hatte :(


    Edit:

    Müsste ich die Zeile dann doppelt eintragen mit dem Inhalt?:

    AutoIt
    For $Match in StringRegExp(FileRead($sVARIABLEFILTEPATH), "(?m)^(.+?)\h*(.*?)\h*$", 4)

    Mein AutoIT Smartphone GUI >>hier<<

    Der Mensch ist das einzige Tier, dass arbeiten muss.

    Einmal editiert, zuletzt von mirko2002 (4. August 2015 um 14:01)

  • Das ist ein sogenannter regulärer Ausdruck. Ein sehr mächtiges Werkzeug um Strings anhand von Abfolgemustern zu zerlegen/zu prüfen oder zu verändern.
    Der Haken: Sich da einzuarbeiten benötigt bisschen Zeit - lohnt sich aber. (Ein Tutorial hierzu findest du z.B. hier).

    Ansonsten geht es auch mit anderen Funktionen.
    Für das Beispiel könnte man z.B. _StringBetween verwenden:

    AutoIt
    $a = _StringBetween($s_VariableFile, "Net Rate ", "€")
    ConsoleWrite($a[0] & @CRLF)

    Im ersten Beispiel wird der Inhalt der Variablendatei direkt ausgelesen ohne sie erst in eine Variable zu speichern.
    Da du jetzt mehrere Abfragen darauf machst solltest du noch das FileRead raus nehmen und das Ergebnis in eine Variable packen.

  • Hi Aspirin Junkie,

    Danke für die Liste .... es ist ja nicht so, dass ich das garnicht verstanden hätte, aber
    (?m) und \h* waren das grosse Unbekannte.
    (Du hattes mir ja schon mal einen RegEx gezeigt/genutzt der so Deine Aussage schon an schwarze Magie herankommt)

    Spoiler anzeigen


    $a_RemoveDirs = StringRegExp($S_ExcludeRAW, '(?:"(.+?))(?R)?(?:")', 3)


    Aber das Thema RegEx ist und bleibt sehr spannend

    Danke

  • Das ist ein sogenannter regulärer Ausdruck. Ein sehr mächtiges Werkzeug um Strings anhand von Abfolgemustern zu zerlegen/zu prüfen oder zu verändern.
    Der Haken: Sich da einzuarbeiten benötigt bisschen Zeit - lohnt sich aber. (Ein Tutorial hierzu findest du z.B. hier).

    Ansonsten geht es auch mit anderen Funktionen.
    Für das Beispiel könnte man z.B. _StringBetween verwenden:

    AutoIt
    $a = _StringBetween($s_VariableFile, "Net Rate ", "€")
    ConsoleWrite($a[0] & @CRLF)


    Im ersten Beispiel wird der Inhalt der Variablendatei direkt ausgelesen ohne sie erst in eine Variable zu speichern.
    Da du jetzt mehrere Abfragen darauf machst solltest du noch das FileRead raus nehmen und das Ergebnis in eine Variable packen.

    Ich stech (nach wie vor :rofl: ) auf dem Schlauch....

    Monaten habe ich den Code soweit umgeschrieben zum testen:


    Mit Deinem Beispiel StringBetween komm ich gerade überhaupt nicht zurecht :(

    LG
    Mirko

    Mein AutoIT Smartphone GUI >>hier<<

    Der Mensch ist das einzige Tier, dass arbeiten muss.