Beiträge von AspirinJunkie

    Wie baut man so eine Url zusammen?

    Ich hatte es so gemacht, geht auch, aber elend langsam,

    Die URL zusammenbauen bedeutet im Prinzip ja nur verschiedene Teilstrings hintereinander zusammen zu kleben.

    Die Variante wie du es gemacht hast, ist exakt die Syntax die man hierfür in AutoIt verwendet.

    Mir ist nur noch nicht klar was du mit "elend langsam" in diesem Zusammenhang genau meinst.
    Die Ausführungsgeschwindigkeit ist es sehr wahrscheinlich nicht - denn das geht flott.

    Ich vermute du meinst eher die Zeit die du zum Zusammenschreiben der Zeile benötigst - also die ganzen Anführungszeichen und &-Operatoren - oder?


    Nun - ja das kann schon etwas aufwendig werden und zwischendurch auch zu Schreibfehlern führen - insbesondere wenn es sehr viele Bestandteile sind.


    Ich werde dir daher mal ein paar Beispiele geben wie du eventuell den String etwas übersichtlicher zusammenbauen kannst.

    Ausdrücklich möchte ich aber nochmal darauf hinweisen, dass die Variante die du genommen hast absolut korrekt und erstmal die präferierte Variante ist - du kannst es problemlos so weiter handhaben.


    1. Befehlszeilenumbrüche einfügen für mehr Übersicht um nicht ewig lange Zeilen zu erhalten.
    Hierzu verwendet man den _-"Operator" am Ende einer Zeile, der signalisiert, dass der Befehl auf der anderen Zeile weitergeht.
    Auf diese Weise kann man Befehle in AutoIt auf mehrere Zeilen aufteilen:

    2. Option "ExpandVarStrings" setzen.

    Wenn man diese Option setzt, dann kann man Variablen direkt in Strings verwenden indem man den Variablennamen in Dollarzeichen einschließt. (Makros in @-Zeichen).

    Man muss nur bisschen aufpassen wenn man Dollar- oder @-Zeichen im String erhalten möchte - die muss man dann durch Dopplung vor einer Interpretation bewahren:

    AutoIt
    Opt("ExpandVarStrings", 1)
    
    Local $Geo =  "50.77677,7.08529:50.72258,7.37596"
    Local $MS = 80
    Global CONST $SAPIKEY_TOMTOM = "..."
    
    Global $url =     "https://api.tomtom.com/routing/1/calculateRoute/$Geo$/json?maxAlternatives=3&language=de-DE&sectionType=traffic&routeType=fastest&traffic=true&avoid=unpavedRoads&travelMode=car&vehicleMaxSpeed=$MS$&key=$SAPIKEY_TOMTOM$"
    
    ConsoleWrite($url & @CRLF)

    3. StringFormat verwenden.

    StringFormat ist eigentlich nur die Umsetzung der guten alten C-Funktion "printf()" für AutoIt.

    Hier definiert man seinen String und setzt darin Platzhalter, welche man auch noch für verschiedene Datentypen anpassen kann.
    Die Werte die dann für die Platzhalter eingesetzt werden sollen, werden dann einfach in der selben Reihenfolge als folgende Parameter der Funktion eingetragen.
    Im einfachsten Fall wäre der Platzhalter ein %s welches angibt, dass dort ein String eingefügt werden soll.

    AutoIt
    Local $Geo =  "50.77677,7.08529:50.72258,7.37596"
    Local $MS = 80
    Global CONST $SAPIKEY_TOMTOM = "..."
    
    Global $url = StringFormat( _
        "https://api.tomtom.com/routing/1/calculateRoute/%s/json?maxAlternatives=3&language=de-DE&sectionType=traffic&routeType=fastest&traffic=true&avoid=unpavedRoads&travelMode=car&vehicleMaxSpeed=%s&key=%s", _
        $Geo, $MS, $SAPIKEY_TOMTOM)
    
    ConsoleWrite($url & @CRLF)

    4. Für jeweiligen Anwendungsfall Helfer schreiben.

    Da wir es hier mit einer URL und GET-Parametern zu tun haben kann man sich das ganze eventuell übersichtlicher gestalten, wenn man die Parameter einzeln als Liste behandelt und sich die URL dann automatisiert zusammenbauen lässt.
    Die GET-Parameter einer URL sind im Grunde nur Schlüssel-Wert-Paare und damit eignet sich eine AutoIt-Map wunderbar um diese strukturiert zu halten.

    Auf die Art kann man sich eine kleine Helferfunktion schreiben und bekommt so evtl. etwas mehr Übersicht in sein Skript:

    Hab jetzt gesehen, dass die Funktionen doch nicht doppelt bezeichnet sind - meine haben einen Unterstrich - die anderen nicht.
    Es sollte daher eigentlich diesbezüglich keine Probleme geben.

    Die zwei Screenshots bringen uns diesbezüglich auch nicht weiter.
    Ein winziges Minimalskript welches den Fehler reproduziert wäre angebracht.


    Ansonsten zwingt dich keiner meine UDF für die JSON-Weiterverarbeitung zu verwenden.
    Du kannst das Skript von oben doch auch einfach so anpassen, dass die Extraktion der Werte über die andere UDF geschieht:

    Der Fehler "unknown function" kommt eigentlich nur wenn die Datei in welcher diese Funktion definiert ist nicht richtig inkludiert wurde.
    Entweder fehlt die #include-Anweisung, oder sie bezeichnet die falsche Datei oder die einzubindende Datei befindet sich in einem anderen Ordner.

    Wenn du die UDF also z.B. in JSON_2.au3 umbenannt hast, aber als include immer noch #include "JSON.au3" dasteht - dann kommt so ein Fehler.

    Das wäre meiner Meinung nach der eigentliche Grund für die Fehler.


    Nun hast du ja aber noch das zweite Phänomen mit den zwei gleichzeitig zu verwendenden UDFs, welche eine Funktion mit gleichem Namen definieren.

    Nun da gibt es eigentlich nur die Lösung, welche Moombas bereits vorschlug:

    Schnapp dir die UDF und änder in der Funktionsdefinition den Namen der Funktion _JSON_Get() (das ist soweit ich es überblicke die einzige die doppelt definiert wird)

    Anschließend verwendest du im Skript diesen neuen von dir gewählten Namen.


    Edit: Sehe gerade, dass die eben nicht doppelt benannt sind. Meine Funktionsnamen haben alle einen Unterstrich am Anfang - die von der anderen UDF nicht.
    Es sollte daher also gar keine Probleme von der Bezeichnung her geben.

    Btw: Ich dachte erst ganz naiv, dass lässt sich doch direkt mit sqlite abfrühstücken.
    Ich trau mir da schon einiges zu, aber tatsächlich bin ich mit der Aufgabe hier per reiner sqlite-Lösung krachend gescheitert.
    Selbst mit window-functions und rekusiven CTEs kam ich nicht ran.


    Also wenn einer etwas blickig ist - das wäre vielleicht ne interessante Challenge um seine sqlite-Kenntnisse zu vertiefen.

    1. ab und an mal schreibt er den Counter nicht mit warum weiß ich nicht.

    Wenn es auftritt, dann nur bei einem einzigen Eintrag?

    Falls ja: Ist ein Sonderfall bei dem der erste Eintrag im (sortierten) Array keine weiteren Elemente mehr in den 5 Minuten hat.

    Lösung: folgendes noch vor die Schleife packen: $aCSV[0][2] = 1


    2. Trotz _ArraySort($aCSV, 0, 0, 0, 1) werden nicht alle Daten nach Datum/Zeit geordnet siehe bild.

    Das Bild sagt mir, dass nicht mein Code verwendet wurde.
    Wenn wir dir helfen sollen musst du uns schon den Code zeigen, der dies hervorbringt.

    Im Bild sind die Zeitangaben in "Col 2" aufgeführt.

    In meinem Code steht dort hingegen die Anzahl und die Zeitangaben stehen hingegen in der zweiten Spalten - der Spalte mit der Nummer 1 (da 0-basiert).

    Versuche es in den Webdriver von Dan einzuarbeiten.

    WebDriver?
    Das ist doch für die Steuerung von Browsern - oder?
    Das ist aber doch Kanonen auf Spatzen für eine Web-API.

    TomTom wird doch sehr wahrscheinlich ähnlich funktionieren wie alle anderen entsprechenden APIs auch.
    Sprich: Man bastelt eine URL zusammen, setzt einen Request hierzu ab und bekommt einen Return.
    Dafür benötigt man doch aber keinen Overhead eines Browsers - ein simples InetRead macht alles was man braucht (siehe mein Beispiel oben mit der Google Geocode-API). Das geht flotter, einfacher und mit weitaus weniger Overhead.


    Oder die TomTom-API ist ganz obskur und macht völlig andere Dinge.


    Wie ist das eigentlich, laufen die alten Sripte noch nach dem Update, oder muss da was angepasst werden.

    Nicht pauschal.
    Wenn man mit der UDF Objekte extrahiert hat und diese direkt in AutoIt weiterverwendet hat und diese dann halt als Dictionary angesprochen hat dann muss man anpassen.
    Wenn man die Objekte aber nicht manuell angefasst hat sondern z.B. nur einzelne Werte mit json_get gezogen hat oder sowas dann gibt es keinen Unterschied.

    Wenn du die UDF verwenden willst und ein Skript neu bastelst dann würde ich stark dazu tendieren die normale json.au3 zu verwenden.
    Dann werden nur native AutoIt-Strukturen verwendet. Außerdem will ich die json_dictionary.au3 nicht weiterpflegen.



    Edit Windi : So hab mir die TomTom-API mal angeschaut und natürlich arbeitet die wie jede andere Web-API auch.
    Sprich - man braucht auch hier kein WebDriver oder sonstiges - ein einfaches InetRead ist hier die korrekte Wahl.
    Dann kann man sich das auch in eine einfache Funktion zur Wiederverwendung gießen:

    Die Url ist von TomTom und der Key kann ich nicht veröffentlichen.

    Dann musst du die Abfrage natürlich noch an die JSON-Struktur die TomTom liefert anpassen:


    Ansonsten grundsätzlicher Hinweis: Fehlermeldungen ohne ein minimales Skript zu posten, welches diese verursacht helfen in der Regel nicht wirklich weiter.


    Edit Musashi : Die Funktion _ArrayAinATo2d() findet sich auch mittlerweile in der ArrayPlus-UDF.

    RegEx hat hier nichts zu suchen.
    Die Ergebnisse sind im JSON-Format und sollten daher auch entsprechend behandelt werden.
    Es gibt diverse UDFs hierzu für AutoIt.

    Ein Beispiel zum Geocoden über Google mit Hilfe >dieser UDF< habe ich dir mal erstellt (das Rohergebnis von dir sagt mir nix, da meine Google-API-Abfragen eine andere Struktur zurückgeben):

    das ist korrekt aber ich brauch den zähler ja nur bei den gefunden doppelten innerhalb 5min das heißt

    Bsp. Gerät 1 sendet 7x innerhalb 5min.

    Ok das mit der Anzahl hatte ich nicht gesehen.

    Natürlich kann man dies mit ergänzen:


    Mein Vorschlag - du benötigst hierfür noch zusätzlich >diese UDF<:

    Beinhaltet im Bereich Name 4 Elemente und id 36 Elemente, richtig?

    Genau.

    Die Zahl in Klammern definiert ein festes Array dieses Datentyps mit der entsprechenden Anzahl an Elementen.

    Das ist klassische C-Syntax und im Speicher stehen diese Elemente einfach hintereinander.


    meine bisherige Annahme, das dies die maximale Zeichenlänge angibt

    Ist auch richtig. Man kann halt nur soviel Zeichen schreiben wie Platz im Char-Array ist.

    Man muss aber nicht so viele schreiben.

    Wenn es weniger werden sollen ist der String halt nullterminiert und gibt so dass vorzeitige Ende an.

    Im Speicher verbraucht es dennoch soviel Platz wie das Array von der Gesamtgröße her definiert wurde. egal ob man nur ein Zeichen reinschreibt oder 100.

    Kann ich bestätigen aber ein Bug ist es Definitionsgemäß meiner Meinung nach nicht.
    Denn: Ein Bug wäre ein Abweichen von einem vordefinierten Verhalten.
    Die Dot-Notation bei DllStruct und insbesondere die Ansprache von Array-Indizes über die Klammer ist jedoch überhaupt nicht definiert - zumindest kann ich in der Hilfe nix hierzu finden.

    Genauso sehen es die AutoIt-Devs auch.


    Es bleibt also ein Austesten undokumentierten Verhaltens und da du diese Variante anscheinend ja dennoch aktiv verwenden willst, wollen wir wenigstens einen Workaround zu deinem Problem finden.

    Die Lösung hierzu lautet: konsequent Doppelklammer nutzen:

    AutoIt
    Global $tStruct = DllStructCreate('uint64 data[3];')
    
    ; Zuweisung und Abfrage ueber eine Variable funktioniert nicht
    For $i = 1 To 3
        $tStruct.data(($i)) = 1234
        ConsoleWrite('@error: ' & @error & ' ')
        ConsoleWrite('$tStruct.data($i) = ' & $tStruct.data(($i)) & @CRLF)
    Next

    In diesem Fall musst du nicht zeilenweise durchgehen oder soetwas.
    Im Grunde musst du nur alle ; durch ersetzen.

    Das geht z.B. so:

    Das eigentliche Script dient zum Import von Registry-Dateien und der Auswertung eventuell auftretender Fehler.

    Da ist die Variante über das extra hierfür vorgesehene Kommandozeilentool reg doch 1000x stabiler.


    Alles was du dafür brauchst ist lediglich eine einzige Zeile:

    AutoIt
    If RunWait('reg import "' & @ScriptDir & "\Test.reg" & '"') <> 0 Then MsgBox(48, "Fehler", "Import der Reg-Datei mit Fehlern beendet")


    Wenn der Fehlertext noch von Relevanz sein sollte, dann ist auch das natürlich möglich:


    Und das alles 10x stabiler und schneller als mit Pixelsearch rumzuopern. Dann stößt du auch nicht nach nem Jahr auf neue Probleme die Pixelsearch verursacht.

    Ich denke so wirst du eher nicht zu einem sinnvollem Ergebnis kommen.

    Mit XY-Problem war gemeint, dass du ein eigentliches Problem lösen möchtest und glaubst die Lösung besteht in der Nutzung von PixelSearch.
    Deine Frage und die Antworten drehen sich dann zwangsläufig darum deine nun entstandenen Problem mit PixelSearch zu lösen obwohl eventuell für das eigentliche Anliegen ein viel besserer Ansatz vorhanden wäre.


    Bitte erkläre also - dir zuliebe - was du im Grunde umsetzen möchtest und löse dich dabei schonmal von deiner bisherigen Lösung mit Pixelsearch.


    Dein Screenshot hilft hier überhaupt nicht weiter, weil jedem klar ist, dass dein Ziel nicht sein kann erst eine blaue Fläche in einer eigenen GUI zu erstellen und diese dann mit PixelSearch zu klicken.
    Der eigentliche Sinn dahinter muss also ein gaaaanz anderer sein.

    Wenn du dies erläuterst wirst du mit ziemlich hoher Sicherheit eine viel bessere Lösung erhalten als der Weg der bislang eingeschlagen wurde.
    Ich programmiere seit >17 Jahren in AutoIt und das wacklige Pixelsearch habe ich noch nie benötigt.

    Geht auch in einem Schritt (nicht die Leerstellen ersetzen sondern die Inhalte neu aufbauen):

    Code
    $_Ausgabe = StringRegExpReplace($_Texteingang, "(.{24})(.{23})\h?", '\1 \2' & @CRLF)
    ConsoleWrite($_Ausgabe & @CRLF)


    Aber hier muss es nicht unbedingt RegEx sein.
    Wer damit noch fremdelt könnte sich das auch folgendermaßen lösen:


    AutoIt
    $sOut = ""
    For $i = 1 To StringLen($_Texteingang) Step 48
        $sOut &= StringMid($_Texteingang, $i, 24) & " " & StringMid($_Texteingang, $i + 24, 23) & @CRLF
    Next
    ConsoleWrite($sOut & @CRLF)

    mit FileMove bekomme ich es so nicht hin.

    Musst halt den Pfad vorher splitten - dann bist du entsprechend flexibel:

    AutoIt
    #include <FileConstants.au3>
    #include <File.au3>
    
    $File = FileOpenDialog("Wähle eine Datei zum einlesen ...", @ScriptDir, "Textdatei (*.txt)|alle Dateien(*.*)", BitOR($FD_FILEMUSTEXIST, $FD_MULTISELECT))
    
    Local $sDrive, $sDir, $sFileName, $sExt
    _PathSplit($File, $sDrive, $sDir, $sFileName, $sExt)
    
    Filemove($File, $sDrive & $sDir & "nachher.123")


    Edit:

    Nimm lieber

    1. FileCopy

    2. (wenn die Quelle nicht mehr gebraucht wird) FileDelete

    Was ist für dich der Grund es so zu machen und nicht einfach mit FileMove()?
    Auf den ersten Blick sehe ich da nur Nachteile und keinen Vorteil - irgendwas übersehe ich vielleicht?

    Urlaubs-und Krankheitstage werden i.d.R. bezahlt, weswegen ich sie nicht abgezogen habe.

    Das sind aber Zeiten in denen du nicht arbeitest.
    Es ging ja explizit darum was du als Gegenleistung für eine tatsächlich geleistete Sekunde Arbeit erhälst.

    Wenn einer Brutto 50.000€ hat und 25 Tage Urlaub hat - ist er da jemandem gleichgestellt der auch 50.000€ Brutto hat aber 100 Tage Urlaub bekommt? - nach deiner Rechnung ja.

    Und ja sehe das auch so: Für einen relevanten Vergleich müssten Urlaubs- / Weihnachtsgelder usw. natürlich mit reingerechnet werden.
    Also im Grunde das ganze Jahresbrutto und auf der anderen Seite die tatsächlich geleisteten Arbeitssekunden - erst dann wird es wirklich vergleichbar.


    sodass ich Urlaubs- und Weihnachtsgeld bekomme, was eigentlich keine freiwillige Leistung des Arbeitgebers ist.

    Da gibt es doch gar keine gesetzliche Regelung? Das ist doch wirklich reine Sache des Arbeitgebers ob er das von sich aus bezahlt oder einem Tarifvertrag beitritt, welcher dies vorsieht.
    Ich z. B. bekomme weder Urlaubs- noch Weihnachtsgeld - das ist also durchaus freiwillig was der Arbeitgeber da macht.


    Edit: Oder meintest du, dass dein 13. Gehalt und Weihnachtsgeld fest im Arbeitsvertrag verankert ist und daher bei deiner Sekundenbruttoberechnung mit reingerechnet werden sollte. Falls ja: So sehe ich das auch.

    ~75.000 € Brutto / Jahr ist ein ordentliches Jahresgehalt für Deutsche Verhältnisse.

    Da komm ich nicht ganz auf die Summe.
    Dänemark hatte 2021 254 Arbeitstage und man hat wohl Anspruch auf mind. 25 Urlaubstage.
    Also hat man dort maximal 229 Tage gearbeitet.

    Ich gehe einfach mal vom klassischen 8h Tag aus dann sieht meine Rechnung so aus:

    0,99869 [ct] / 100 * 60 [s] * 60 [min] * 8 [h] * 229 [Tage] = 65.865,60 €