1. Dashboard
  2. Mitglieder
    1. Letzte Aktivitäten
    2. Benutzer online
    3. Team
    4. Mitgliedersuche
  3. Forenregeln
  4. Forum
    1. Unerledigte Themen
  • Anmelden
  • Registrieren
  • Suche
Alles
  • Alles
  • Artikel
  • Seiten
  • Forum
  • Erweiterte Suche
  1. AutoIt.de - Das deutschsprachige Forum.
  2. Mitglieder
  3. aSeCa

Beiträge von aSeCa

  • Array über Programmdauer hinweg speichern

    • aSeCa
    • 23. März 2024 um 18:53
    Zitat von Musashi

    Ja !

    Alternativ könntest Du aus dem "echten" Datum einen (Unix)-Timestamp machen und den als zusätzliches Feld in die Tabelle eintragen (nur für die SQL Abfrage) -> SELECT ... ORDER BY timestamp.

    Sofern Du die DB-Tabelle jedesmal neu anlegst und die Daten in der vorhandenen Sortierung in die DB einträgst, dann sollte eigentlich bereits die ID (SELECT x,y FROM tabelle ORDER BY id) ausreichen.

    Ich habe eine eigene ID, also keine hochlaufende. Über die Zeit fühlt sich schon besser an :)

    Unix-Timestamp ist dann im DB-Browser nicht so gut nachzuvollziehen, ich schaue mal, ob das Sortieren auch mit dem Datum als TEXT nach ISO8601 formatiert gut geht. Und sonst hast du mich halt auch auf die Idee gebracht, dass ich es auch mit einer Andersformatierung einfach so lösen kann, danke! :)
    =>

    Code
    #include <Array.au3>
    
    ;~ Dim $aArray[3][3] = [["ABC", "", "23.03. 13:37"], ["BCD", "", "23.03. 09:41"], ["CDE", "", "15.04. 15:15"]]
    Dim $aArray[6][3] = [["ABC", "", "2024-03-23 13:37:25"], ["BCD", "", "2024-03-23 09:41:15"], ["CDE", "", "2024-04-15 15:15:15"], _
    					["DEF", "", "2024-04-15 04:15:55"], ["EFG", "", "2023-12-31 15:15:15"], ["FGH", "", "2024-07-01 05:25:15"]]
    
    _ArrayDisplay($aArray)
    _ArraySort($aArray, 1, 0, 0, 2) ; reicht aus :D
    _ArrayDisplay($aArray)


    *edit*
    Aber in dem Format hat es wirklich gereicht, dann einfach meinen Call in _readMessageDatabase so anzupassen, super! :)
    _getData("SELECT * FROM " & $mDatabase.tableName & " ORDER BY date DESC")

    => läuft auch eingesetzt in mein Programm genau richtig - danke dir! :)

  • Array über Programmdauer hinweg speichern

    • aSeCa
    • 23. März 2024 um 18:22
    Zitat von Musashi

    Kurze Frage zum Verständnis :

    Speicherst Du [Datum Uhrzeit] wirklich im Format "TT.MM. hh:mm" , d.h. ohne Jahr und Sekunden ?

    Ich bekomme es anders, aber ich lege es auch so ab, ja. Theoretisch könnte ich die Daten natürlich sauberer abspeichern (auch für einen sauberen Datums-Datentyp in der DB... hmmm) und dann nur für die Anzeige so bearbeiten...^^ Ich benutze die wunderschöne UDF "_Date_Time_Convert" :D


    Vllt. geht die Frage in sogar in die Richtung? Kann ich, wenn ich das als richtiges Datum in die DB lege, via Query danach sortieren? Daran hatte ich noch gar nicht gedacht... Wenn das geht, wäre das sicherlich die smarteste Variante... :)!


    *edit*

    Laut Doku gibt es wohl keinen Date-Datentypen, schade...^^ Aber gibt date- und time-Funktionen, wenn man es richtig ablegt, also als "YYYY-MM-DD HH:MM:SS.SSS". Aber wenn ich mir das Format so anschaue (vllt. ohne die Millisekunden), dann sollte auf dem Format auch eine normale Sortierfunktion das richtig hinbekommen... Das wäre auch noch eine Variante. ^^

  • Array über Programmdauer hinweg speichern

    • aSeCa
    • 23. März 2024 um 14:20

    Ich habe jetzt den Code in ein Script eingebaut und ein paar Dinge sind dabei aufgefallen. Davon hänge ich grade an einem Punkt und wollte mal nach einem Best Practice dazu fragen:

    Die Reihenfolge des Arrays geht verloren, wenn ich es in der DB zwischenspeichere. Da ich einen Teil der Nachrichten in eine ListView packe, brauche ich die richtige Reihenfolge. Diese ist ja dem Datum entsprechend, weil in der Mailbox die neuen Nachrichten auch oben sind.

    Ich dachte erst daran, die ListView zu sortieren. Die normale Sortierfunktion ist wohl nicht ausreichend und "GUICtrlRegisterListViewSort" sieht unnötig kompliziert dafür aus.

    Darum wollte ich dann direkt das Array sortieren. ArraySort() alleine reicht auch nicht aus, weil er nicht richtig das Datum auswerten kann.

    Was wäre jetzt der einfachste Weg, die Sortierung wieder zu bekommen?

    • Doch mit laufender ID in der Datenbank arbeiten und dann absteigend der ID nach sortieren?
    • An eigene Sortierfunktion für das Array machen?
    • UDF suchen, die Daten sortieren kann und dann Datum für Input und nach Output umwandeln?
    • ...?


    Ich tendiere dazu, die laufende ID zu nehmen, aber so richtig "sauber" fühlt sich das nicht an. Habe irgendwie Sorge, dass es da "Nebenwirkungen" gibt, die ich grade nicht auf dem Schirm habe...^^


    Hier nochmal ein Mini-Datensatz mit meinem verwendeten Datums-Format:

    Code
    #include <Array.au3>
    
    Dim $aArray[3][3] = [["ABC", "", "23.03. 13:37"], ["BCD", "", "23.03. 09:41"], ["CDE", "", "15.04. 15:15"]]
    
    _ArrayDisplay($aArray)
    _ArraySort($aArray, 0, 0, 0, 2) ; reicht nicht aus
    _ArrayDisplay($aArray)
  • Array über Programmdauer hinweg speichern

    • aSeCa
    • 22. März 2024 um 18:54

    Ohja, klar :D kA, warum ich die einzeln übergeben habe ^^ Danke

    Die Erklärung zum BOOL auch sehr aufschlussreich! :)


    Zu dem 2x starten: Also ich lese die Mails ja jedes Mal wieder ein, wenn ich das Postfach öffne. Und dann muss ich ja feststellen, welche davon neu sind?! Also wird das doch permanent passieren?!

    Ganz auf das Array zu verzichten ist auch eine Idee... Ich will halt einige von den Mails in einer ListView anzeigen lassen (letzte 100 oder so). Ich dachte mir, dass es schneller ist, wenn ich das direkt parat habe und nicht erst abrufen muss. Aber hat natürlich auch echt was für sich, die Daten nicht doppelt halten zu müssen und dann direkt die DB zu fragen.

    Aber trotzdem wird die DB ja gefüttert, indem ich das Postfach parse (immer die letzten 100 Nachrichten von der ersten Seite) und dann habe ich da ein Array mit ID, Titel und Datum und werde abgleichen müssen, welche Nachrichten neu sind. Mit jetzigem Wissen würde ich versuchen, die 100 Nachrichten einzutragen und bei 99 schlägt es dann fehl.

    Oder ich merke mir, was die letzte Nachricht war, bzw. frage mir immer die Nachricht mit dem neusten Darum ab und gucke dann, ob es neuere Nachrichten gibt... Wäre vielleicht smarter, hmm! :)


    Danke wegen der Hinweise zu IGNORE und UPDATE, schaue ich mir an! :)

  • Array über Programmdauer hinweg speichern

    • aSeCa
    • 22. März 2024 um 17:18

    Danke für eure Inputs :)
    Die UDF, um als einen String abzuspeichern, das hört sich echt gut an. ^^ Sowas hatte ich im ersten Schritt gesucht :) Das werde ich auf jeden Fall mal ausprobieren und einsetzen, ich bin mir nur noch nicht sicher, ob für diesen Fall.

    Mit JSON und ich glaube einer anderen JSON-UDF habe ich auch schon gearbeitet. Das wäre auf jeden Fall leichter zu handhaben, ja. Aber wenn Datenbank "richtig" wäre, versuche ich mich damit ^^ Ich versuche gerne den richtigen Weg zu gehen und dabei dann noch was zu DBs zu lernen ist ja auch praktisch ^^

    Ich schaue mir auf jeden Fall schon mal eure Funktionen zum Umgang mit SQLite an. Sieht auf jeden Fall schon sehr nützlich aus.


    Kanashius, du würdest also jede Mail als eigene .txt ablegen? Da kommen dann schon einige zusammen, aber ist wahrscheinlich eine alles Ressourcen-schonend zu machen... Ist es denn sinnvoll, eine UUID zu generieren, wenn die Mails schon eine eindeutige ID haben, die ich auch ablege? Ich würde die einfach nutzen, oder? Und das "AUTOINCREMENT" beim Erstellen der Tabelle dann rausnehmen.


    Ich habe jetzt mal, bis auf das Abspeichern einer Datei je Message (wenn noch nicht vorhanden), den Teil mit der Datenbank mit eurem Input versucht:

    Spoiler anzeigen
    C
    #include <SQLite.au3>
    #include <Array.au3>
    
    Global $mDatabase[], $aMailbox
    $mDatabase["filePath"] = @ScriptDir & "\Data\messages.db"
    $mDatabase["tableName"] = "messages"
    
    Enum $MAIL_ID, $MAIL_STATUS, $MAIL_TITLE, $MAIL_DATE, $MAIL_SENDER, $MAIL_ANALYZED
    
    If Not _openDatabase($mDatabase.filePath) Then ConsoleWrite("DB konnte nicht geladen werden!")
    
    writeStuff()
    readStuff()
    
    _closeDatabase()
    ;~ _deleteDatabase()
    
    Func writeStuff()
    	Local $mMessage[]
    
    	$mMessage.status = "unread"
    	$mMessage.title = "Newsletter XY"
    	$mMessage.date = "21.03. 15:15"
    	$mMessage.id = "g4g43g4g54"
    	$mMessage.sender = ""
    	$mMessage.analyzed = False
    
    	_addMessageToDatabase($mMessage.id, $mMessage.status, $mMessage.title, $mMessage.date, $mMessage.sender, $mMessage.analyzed)
    EndFunc
    
    Func readStuff()
    	Local $aResult = _getData("SELECT * FROM " & $mDatabase.tableName)
    	Local $mMessage[], $aMailbox[UBound($aResult)]
    
    	_ArrayDelete($aResult, 0)
    	_ArrayDisplay($aResult)
    
    	For $i = 0 To UBound($aResult) - 1
    		Dim $mMessage[]
    
    		$mMessage.status = $aResult[$i][$MAIL_STATUS]
    		$mMessage.title = $aResult[$i][$MAIL_TITLE]
    		$mMessage.date = $aResult[$i][$MAIL_DATE]
    		$mMessage.id = $aResult[$i][$MAIL_ID]
    		$mMessage.sender = $aResult[$i][$MAIL_SENDER]
    		$mMessage.analyzed = $aResult[$i][$MAIL_ANALYZED] == "True" ? True : False
    
    		$aMailbox[$i] = $mMessage
    	Next
    
    	ConsoleWrite($aMailbox[0].title & @CRLF)
    EndFunc
    
    Func _getData($sSql)
    	Local $aData[0], $iRows, $iCols
    	Local $sResult = _SQLite_GetTable2D($mDatabase.db, $sSql, $aData, $iRows, $iCols)
    	If @error Then Return SetError(1, $sResult&" >> "&@error, $aData)
    
    	Return $aData
    EndFunc
    
    Func _openDatabase($sFile = ":memory:")
    	$mDatabase["dllPath"] = _SQLite_Startup("Data\sqlite3.dll", False, 1)
    	If @error Then Return SetError(1, @error, False)
    
    	$mDatabase["db"] = _SQLite_Open($sFile)
    	If @error Then Return SetError(2, @error, False)
    
    	_SQLite_Exec(-1, "CREATE TABLE IF NOT EXISTS " & $mDatabase.tableName & " (id TEXT NOT NULL PRIMARY KEY, status TEXT NOT NULL, title TEXT NOT NULL, date TEXT NOT NULL, sender TEXT, analyzed BOOL NOT NULL);")
    
    	Return True
    EndFunc
    
    Func _closeDatabase()
    	If MapExists($mDatabase, "db") And $mDatabase.db<>0 Then
    		_SQLite_Close($mDatabase.db)
    		$mDatabase.db = 0
    	EndIf
    
    	If MapExists($mDatabase, "dllPath") And $mDatabase.dllPath<>0 Then
    		_SQLite_Shutdown()
    		$mDatabase.dllPath = 0
    	EndIf
    EndFunc
    
    Func _deleteDatabase()
    	FileDelete($mDatabase.filePath)
    EndFunc
    
    Func _executeQuery($sQuery)
        _SQLite_Exec($mDatabase.db, $sQuery)
    EndFunc
    
    Func _addMessageToDatabase($sId, $sStatus, $sTitle, $sDate, $sSender, $bAnalyzed)
    	Local $sQuery = "INSERT INTO " & $mDatabase.tableName & "(id, status, title, date, sender, analyzed) VALUES ("
    
    	$sQuery &= "'" & $sId & "'" & "," & "'" & $sStatus & "'" & "," & "'" & $sTitle & "'" & "," & "'" & $sDate & "'" & "," & "'" & $sSender & "'" & "," & "'" & $bAnalyzed & "'"
    	$sQuery &= ")"
    
    	_executeQuery($sQuery)
    	If @error Then Return SetError(1, @error, False)
    
    	Return True
    EndFunc
    Alles anzeigen


    Das gefällt mir vom Handling schon ganz gut... Müsste dann noch eine Funktion bauen, um z. B. den Sender nachträglich eintragen zu können, wenn die Nachricht geöffnet und geparst wurde. Und dann das mit den Files halt.

    Hätte bislang 2 neue Fragen:

    • Muss ich das mit dem BOOLEAN so handhaben? Also im Prinzip kriege ich via AutoIt nur alles als String rein/raus und muss dann selber umwandeln? Dann könnte ich statt BOOL auch gleich TEXT nehmen, oder hat das einen Vorteil?!
    • Wenn ich das Script 2x starte und dazwischen nicht die DB lösche, kriege ich beim Eintragen natürlich einen Fehler in der Konsole: "UNIQUE constraint failed: messages.id"; das ist grundsätzlich auch gut, aber ist das das richtige Vorgehen oder sollte man irgendwie erstmal prüfen, ob schon ein Eintrag da ist? Das knallt mir dann später ja auch heftig die Konsole voll...


    Und gibt es grundsätzlich Feedback zu meinem Handling? Habe ja viel übernommen, aber auch Sinnhaftigkeit vom Enum, Erweiterung der $mDatabase, die _addMessageToDatabase(), usw...


    Danke euch! :)

  • Array über Programmdauer hinweg speichern

    • aSeCa
    • 22. März 2024 um 13:13

    Hey,

    immer, wenn ich bisher in Programmen Werte speichern wollte, habe ich das via INI gemacht oder auch via Registry. Jetzt habe ich den Fall, dass ich auch ganz lange Strings abspeichern will und da kommen mir beide Lösungen nicht so gut vor?! Im Prinzip lese ich meine Mails aus und will den Inhalt auswerten (nach Absender, Datum, Titel, Inhalt, etc.) und die Ergebnisse speichern, plus den HTML-Code (ca. 20k Zeichen, sofern ich nicht noch zusätzlich cutte), um später ggf. noch andere Dinge auswerten zu können.

    Ich habe ein Array für die ganze Mailbox und jede Mail ist eine Map mit ein paar der genannten Eigenschaften.

    Auf die Daten muss ich nicht viel zugreifen, es kommt halt immer mal wieder eine Mail rein oder ich werte auch nochmal nachträglich eine Message aus und fülle eine weitere Eigenschaft, aber im Prinzip arbeite ich nur mit dem Array. Falls das Script abstürzt oder der PC mal neustartet, wollte ich die Speicherung parallel zur Veränderung des Arrays halten. An sich könnte ich neue Mails ja auch nachträglich, wenn das Programm wieder läuft, aus dem Postfach laden und ich "verliere" die Daten ja nicht wirklich. Aber es "fühlt" sich irgendwie falsch an, Daten, die ich schon geholt / ausgewertet habe, dann nicht zu behalten. ^^

    Da prüfen, ob ein Eintrag existiert oder existiert, aber noch weniger Informationen hat und entsprechend dann den Eintrag erstellen oder ergänzen mir in SQLite schwierig vorkommt (und ich mit AutoIt echt wenig an Beispielen / Tutorials finde), wollte ich dann die Datenbank bei jeder Anpassung des Arrays einfach löschen und neu erstellen, weil ich im Prinzip ja nur das Array sichern will (auch, wenn das irgendwann natürlich schon sehr groß wird).

    Hatte auch etwas Code, um das grundsätzlich auszuprobieren und mit SQLite "warm zu werden" (also kein schöner Code, ist zum Testen, bevor ich es verwende^^):

    Spoiler anzeigen
    C
    #include <MsgBoxConstants.au3>
    #include <SQLite.au3>
    #include <Array.au3>
    
    Global $mMessage[]
    $mMessage.status = "unread"
    $mMessage.title = "Newsletter XY"
    $mMessage.date = "21.03. 15:15"
    $mMessage.id = "g4g43g4g54"
    $mMessage.sender = "Seller"
    $mMessage.analyzed = False
    $mMessage.html = "<HTML>...</HTML>"
    
    Local $sSQliteDll = _SQLite_Startup("Data\sqlite3.dll", False, 1)
    If @error Then
        MsgBox($MB_SYSTEMMODAL, "SQLite Fehler", "SQLite3.dll konnte nicht geladen werden!")
        Exit -1
    EndIf
    
    Global $hMessagesDb = _SQLite_Open(@ScriptDir & "\Data\messages.db")
    
    _SQLite_Exec($hMessagesDb, 'CREATE TABLE Messages (status, title, date, id, sender, analyzed, html);')
    _SQLite_Exec($hMessagesDb, 'INSERT INTO Messages VALUES ("' & $mMessage.status & '", "' & $mMessage.title & '", "' & $mMessage.date & '", "' & $mMessage.id & '", "' & $mMessage.sender & '", "' & $mMessage.analyzed & '", "' & $mMessage.html & '");')
    
    Local $aResult, $iRows, $iColumns
    
    _SQLite_GetTable2d($hMessagesDb, 'SELECT * FROM Messages;', $aResult, $iRows, $iColumns)
    _ArrayDelete($aResult, 0)
    Dim $aMailbox[UBound($aResult)]
    
    For $i = 0 To UBound($aResult) - 1
    	Dim $mMessage[]
    
    	$mMessage.status = $aResult[$i][0]
    	$mMessage.title = $aResult[$i][1]
    	$mMessage.date = $aResult[$i][2]
    	$mMessage.id = $aResult[$i][3]
    	$mMessage.sender = $aResult[$i][4]
    	$mMessage.analyzed = $aResult[$i][5] == "True" ? True : False
    	$mMessage.html = $aResult[$i][6]
    
    	$aMailbox[$i] = $mMessage
    Next
    
    _ArrayDisplay($aMailbox, "Results from the query")
    ConsoleWrite($aMailbox[0].title & @CRLF)
    
    _SQLite_Close($hMessagesDb)
    _SQLite_Shutdown()
    
    FileDelete(@ScriptDir & "\Data\messages.db")
    Alles anzeigen


    Jetzt stehe ich vor ein paar Fragen:

    • Ist es für den Use Case überhaupt notwendig / sinnvoll, SQLite zu verwenden (v. a. nur wegen der Stringlänge vom HTML-Code)? Oder geht das doch "smarter"? ^^
    • Oder sollte ich sogar grundsätzlich, wenn davon auszugehen ist, dass es irgendwann 1000+ Mails sind, weg von einem Array und direkt auf der Datenbank arbeiten? (ich stelle den Inhalt des Arrays auch in einem Listview dar, wobei ich das vllt. aber später noch auf die 100 letzten oder so begrenze)
    • Kennt ihr Beispiele, mit denen ich mir für SQLite aneigenen kann? Vor allem halt das Thema => Ist ein Eintrag mit einer bestimmten ID da? Wenn ja, hat er auch z. B. schon "analyzed = True"? Und je nachdem, was im Array steht, wird er hinzugefügt, es passiert nichts oder es werden nur die Ergebnisse der Auswertung hinzugefügt (im ersten Zuge hole ich immer nur Status, Title, Datum und ID aus der Mailbox-Übersicht)


    Danke für euren Input! :)

    *edit*
    Ein Gedanke kam mir noch: Vielleicht auch wie gewohnt die ganzen Informationen einfach in die Registry und dann nur für das HTML eine eigene Datenbank... Dann wäre das Handling weiter einfach und die großen Strings liegen woanders. Es braucht dann ja auch keine Anpassungen in der Datenbank, es kommen nur neue Einträge dazu und den einfachen Check, ob schon da oder nicht, das sollte mit WHERE und der ID dann ja klappen... Dann könnte ich auch den ganzen HTML-Kram aus meinem Speicher / dem Array rauslassen und nur bei Bedarf holen *hmmm* ...

  • Maps mit Arrays (Map in Array in Map)

    • aSeCa
    • 15. März 2024 um 18:54
    Zitat von AspirinJunkie

    Doch natürlich kannst du dort ein Array speichern:

    Ahh.... Hatte

    Code
    _ArrayDisplay($mData.parts[0].otherValue)

    versucht. Aber so ging es dann:

    Code
    $aTemp = $mData.parts[0].otherValue
    _ArrayDisplay($aTemp)


    Zitat von AspirinJunkie

    Maps sind nicht unflexibler als Arrays. Bei verschachtelten Arrays verhalten sich diese genauso wie verschachtelte Maps.

    Hm, vielleicht habe ich auch etwas falsch gemacht... Aber meine Versuche, eine Map in eine Zwischen-Variable abzuspeichern, um dann etwas da rein schreiben zu können und die Map wieder im Array abzulegen, das bei meinen Versuchen nicht geklappt.

  • Maps mit Arrays (Map in Array in Map)

    • aSeCa
    • 15. März 2024 um 17:45

    Danke dir, das ist schade... Wenn ich dann da wieder ein Array speichern will, dann klappt das mit der UDF auch nicht mehr. Mache mich ja schon echt unflexibel mit Maps, wenn die hier an ihre Grenzen kommen, hmmm...

    Habe es auch mal mit einem 2D-Array in einer Map versucht. Da geht auslesen auch problemlos, aber beim Schreiben gibt es die gleichen Probleme... Also bei komplexeren Daten dann wohl doch wieder zum Array zurück...^^

  • Maps mit Arrays (Map in Array in Map)

    • aSeCa
    • 15. März 2024 um 15:43

    Hey, ich habe angefangen, mehr Maps zu verwenden und gefällt mir ganz gut. Aber ich bin jetzt in einem Fall etwas ratlos, wie man damit umgeht oder ob da eine Grenze von Maps ist:

    Ich habe eine große Map mit vielen Einträgen, einer davon ist ein Array mit einer Liste an dazugehörenden Einträgen und diese Einträge haben wieder Eigenschaften, die ich über eine Map lösen wollte. (Ich könnte natürlich einfach "große Map -> 2D-Array" machen, aber hätte die Eigenschaften gerne vom Handling wieder über eine Map gelöst)

    Ist etwas abstrakt, daher mal Code, um das Problem zu zeigen:

    Code
    Local $mData[] ; Große Map
    Local $aArray[1] ; Array mit Liste zusammengehörender Teile
    Local $mMapOther[] ; Kleine Map mit Eigenschaften der Teile im Array
    
    $mMapOther["otherValue"] = "other"
    $aArray[0] = $mMapOther
    
    ConsoleWrite($aArray[0].otherValue & @CRLF)
    
    $mData["parts"] = $aArray[0] ; nicht gewolltes Verhalten (s. u)
    
    ConsoleWrite($mData.parts.otherValue & @CRLF)
    
    $mData.parts.otherValue = "nein"
    
    ConsoleWrite($mData.parts.otherValue & @CRLF)
    
    ; ----- oben läuft durch
    ConsoleWrite("-----" & @CRLF)
    
    Local $mData[] ; Große Map
    Local $aArray[1] ; Array mit Liste zusammengehörender Teile
    Local $mMapOther[] ; Kleine Map mit Eigenschaften der Teile im Array
    
    $mMapOther["otherValue"] = "other"
    $aArray[0] = $mMapOther
    
    $mData["parts"] = $aArray ; Ich will ja das Array ablegen, nicht das erste Teil der Liste
    
    ConsoleWrite($mData.parts[0].otherValue & @CRLF)
    
    $mData.parts[0].otherValue = "nein"
    
    ConsoleWrite($mData.parts[0].otherValue & @CRLF)
    Alles anzeigen


    Der erste Teil läuft, ist ja recht klar. Aber ich möchte ja das ganze Array ablegen (2. Teil) und da bekomme ich "Variable must be of type "Object".". Habe auch schon verschiedene andere Konstellationen versucht, das Array erst zwischenzuspeichern und dann wieder in die Map schreiben zu wollen, etc. Aber ich kriege die Konstellation nicht zum Laufen.

    Was ich dann noch machen wollen würde, ist die Map im Array zu erweitern, irgendwie so in der Art (auch verschiedene Konstellationen versucht):

    Code
    $mData.parts[0]["otherOtherValue"] = "otherOther"


    Lässt sich das irgendwie machen oder sollte ich es nicht so kompliziert machen und statt so zu verschachteln (was ich wegen dem Map-Handling machen wollen würde) einfach 2D-Arrays in der Map nutzen?

  • Durchschleifen einer ArrayList und dabei einzelne Listeneinträge löschen

    • aSeCa
    • 6. März 2024 um 15:41

    Alles klar, dankeschön! :)

  • Durchschleifen einer ArrayList und dabei einzelne Listeneinträge löschen

    • aSeCa
    • 6. März 2024 um 15:19

    Hatte zum Lernen einfach mal einige Arrays durch ArrayLists ersetzt (wegen deinem guten Beitrag: Alternativen zum Array ^^) und bislang war ich damit auch ganz happy. Notfalls muss ich refaktorieren, aber kann doch nicht sein, dass der Datentyp bei so etwas Grundsätzlichem dann schon an seine Grenze kommt? ^^'

    Müsste schon einige Stellen anfassen und mir angucken, wie die verschiedenen Operationen in Maps gehandhabt werden... :( Das würde ich lieber erstmal "einfach" Lösen und mir auf die ToDo-Liste schreiben, als es direkt zu machen :D

  • Durchschleifen einer ArrayList und dabei einzelne Listeneinträge löschen

    • aSeCa
    • 6. März 2024 um 15:04

    Hey zusammen,

    ich mache grade etwas mit einer ArrayList und bin dabei auf einen Fehler gestoßen, den ich herleiten konnte:

    Code
    $ObjList = ObjCreate("System.Collections.ArrayList") ; create
    
    $ObjList.Add("Test")
    $ObjList.Add("Wort")
    $ObjList.Add("Hallo")
    $ObjList.Add("Ja")
    
    
    For $sWord in $ObjList
    	MsgBox(4096,"", $ObjList.count)
    	If checkForX($sWord) Then $ObjList.Remove($sWord)
    Next
    
    
    Func checkForX($sString)
    	Return StringInStr($sString,"e") > 0
    EndFunc
    Alles anzeigen

    Sobald ich in der Schleife einen Wert entferne, hört die Schleife einfach auf. Egal, ob an 1. Stelle oder sonst wo. Ich würde gerne mehrere Werte aus einer ArrayList anhand von bestimmten Kriterien entfernen. Ich möchte es dafür nicht in ein Array umwandeln. Gibt es da irgendeine einfache Möglichkeit?

    "Workaround" in meinem Kopf wäre ein Hilfsarray mit den Werten, die raus sollen und danach dann einfach das Array durchschleifen mit .Remove auf der ArrayList. Aber kann mir nicht vorstellen, dass das der beste Weg ist?! :/ Dann habe ich ja auch wieder die "unschönen" ArrayAdd-Operationen ^^

  • ISN AutoIt Studio

    • aSeCa
    • 5. März 2024 um 16:38
    Zitat von ISI360

    aSeCa:
    Im Anhang eine gefixte Version des Formstudios. Hier sollte der Bug mit den Umlauten beim Extracode behoben sein. Du wirst dennoch die Umlaute einmal wieder korrigieren müssen..dann sollte es aber so bleiben.
    Die Datei entpacken und die darin enthaltene formstudio2.a3x einfach im ISN AutoIt Studio Verzeichnis unter \Data\Plugins\Formstudio2 austauschen.

    PS: Die funktion "Tabseite merken" bei Rückgängig/Wiederherstellen ist in der Version auch schon eingebaut ;)

    Klappt beides, danke! :)

    Wenn ich dich schon hier "habe" (^^), eine Frage noch, von der ich nicht genau weiß, ob das ein generelles GUI-AutoIt-Problem ist, oder das irgendwie von ISN getriggert wird, vllt. hast du das schon mal irgendwo beobachtet?! (habe nach viel Google-Suche nichts gefunden, vllt. falsche Stichwörter oder halt doch spezielles Problem)
    => Beim Umgang mit Tabs habe ich immer wieder das Problem, dass sowohl in ISN, als auch kompiliert dann Controls von anderen Tabs "durchscheinen". Also Beispiel: Habe 5 Tabs und starte auf Tab 1, aber 2 Controls von Tab 2, 1 Control von Tab 3 und 6 Controls von Tab 5 sind sichtbar. Wenn ich dann manuell alle Tabs durchgehe, dann verschwindet das und die Tabs wissen wieder, wo sie hingehören...


    Hatte als Workaround das genutzt, das hat auch mal geklappt, aber dann irgendwie doch wieder nicht mehr...^^
    For $t = 7 To 0
        _GUICtrlTab_SetCurSel($tab, $t)
    Next


    Ich habe versucht, das in einem kleinen Beispielscript nachzustellen, aber da läuft alles sauber. Also könnte ich nur Glück haben, dass dir das schon mal begegnet ist...^^

  • ISN AutoIt Studio

    • aSeCa
    • 5. März 2024 um 13:45

    Oh, es gibt so ein Schloss... Sowas habe ich gesucht, wie konnte ich das übersehen? Danke! ^^' Das mit "STRG" klappt auch, ist auch intuitiv... Ich glaube, ich hatte es bei Checkboxen versucht und die wurden dann "gecheckt", statt ausgewählt, und dann dachte ich, dass es nicht geht. Aber muss nur mehr auf das Label zielen, dann geht es da auch.

    Die Demo-Projekte hatte ich bisher nicht gesehen, schaue ich mir an. Danke! :) Dann muss ich wohl mal der Reihenfolge rumspielen usw. Fand es aber komisch, dass ich zumindest bei dem Control dann nicht einfach das Extracode direkt vom Control nutzen kann. Hätte gedacht, dass es genau für sowas da ist.

    Habe jetzt auch schon herausgefunden, warum es bei mir nicht ging: Ich habe die GUI-Breite für die Berechnung genutzt und die kriege ich ja erst ausgelesen, wenn die GUI gebaut ist und wenn sie gebaut ist, muss der Code schon durch sein ^^ Also musste das Auslesen der Breite mit in den Extracode schreiben, dann geht es. Und Fehlermeldung nicht gesehen, weil der Log ja nicht sichtbar ist ist, wenn man den Form Designer offen hat => Doofer Fehler von mir ^^

    Aber einen Bug habe ich so noch festgestellt: Immer, wenn ich Extracode öffne, gibt es wachsende Probleme mit Umlauten:

    Original: _GUICtrlStatusBar_SetText($hStatus, "Noch keine Log-Einträge", 4)

    2. Öffnen des Extracodes: _GUICtrlStatusBar_SetText($hStatus, "Noch keine Log-Einträge", 4)

    3. Mal "Ok" und einfach wieder "Extracode": _GUICtrlStatusBar_SetText($hStatus, "Noch keine Log-Einträge", 4)

    usw. Ist nicht bei jedem Klick, aber das Konstrukt wächst immer weiter. Bei Sonderzeichen noch schlimmer, z. B. hat nach 6x öffnen sich ein einzelnes Sonderzeichen in das verwandelt: "✉"

  • ISN AutoIt Studio

    • aSeCa
    • 20. Februar 2024 um 11:53

    Ich hätte auch noch eine Frage zum Form Designer in ISN: Wie kann ich Radio Buttons gruppieren? Ich kann das ja schwer im Extra Code machen, weil man ja eig. vorher und nachher einmal GUICtrlCreateGroup aufruft und so genau kann man nicht eingreifen, wenn man den Code nicht generiert verwendet, sondern als ISF.

    Und da die Funktion auch nicht irgendwie auf Handles angewendet werden kann, muss man ja an die richtigen Stellen im Code... Ein einfaches Gruppenfeld reicht zumindest nicht aus, hätte ja sein können, dass ISN das dann interpretiert.

    Ich kann halt als Workaround dann als ClickEvent das selber handeln, aber es gibt doch bestimmt auch in ISN einen Weg, um das richtig zu machen?!

  • Data Collection-Variables / Maps in AutoIt - Status?

    • aSeCa
    • 19. Februar 2024 um 17:17

    Danke Mars, habe das mal so übernommen und meine beiden größten ARRAYS mit ENUMS ausgestattet. Sind zwar etwas lang teilweise, aber es ist auf jeden Fall wesentlich leserlicher und macht es viel, viel einfacher!


    Danke auch für dein Beispiel, Kanashius. Die Punktschreibweise gefällt mir auch sehr gut. Auswendig muss man die Keys bei Mars Vorschlag ja nicht kennen, ich kann jetzt auch einfach den übergreifenden Teil des Namens eintippen und dann durch alle passenden Variablen scrollen. Ich habe grade etwas rumprobiert und bei der Lösung ist es doch auch so, dass SCITE nicht die möglichen Key anbietet, sondern nur die, die schon mal genauso in der Kombination irgendwo im Code sind, oder? Ich habe mal ganz oben noch $mData["value3"] = "Value 3" gesetzt und dann kam value3 nicht als Vorschlag, wohl, weil ich noch nirgends $mData.value3 so geschrieben hatte.

    Das ist etwas schade, dann würde sich das schon fast nach meiner alten Java-OOP-Erfahrung anfühlen :D

    Aber es ist auf jeden Fall platzsparender und auch sehr intuitiv. Ich werde mir das Beispiel auf jeden Fall auch nochmal genauer anschauen. Danke! :)

  • Data Collection-Variables / Maps in AutoIt - Status?

    • aSeCa
    • 19. Februar 2024 um 14:27

    Ah, super. Danke! :)


    Ich habe auf jeden Fall grade Enums für mich entdeckt und versuche das auf jeden Fall als ersten Schritt. Aber ich werde danach auch etwas mit Maps experimentieren und das vllt. später dann noch umbauen :)


    Hast du vielleicht noch einen Tipp bzgl. der Notation bei Enums? In der AutoIt-Docu wird "e" für den Anfang der Variable genutzt, aber grade mit deinem Input zu Maps habe ich grade so im Kopf "wäre ja nett, wenn man erkennt, was da für ein Datentyp drin steckt"...

    Ich wäre jetzt so bei z. B. "$eHeight_i", "$eSpareParts_a", $eName_s", usw... Ist das sinnvoll oder hast du da vllt. noch einen Insights in deine Best Practices? :)

  • Data Collection-Variables / Maps in AutoIt - Status?

    • aSeCa
    • 19. Februar 2024 um 13:40

    Danke schon mal für eure Inputs :) Auf jeden Fall gut zu wissen, dass man Maps bedenkenlos verwenden kann. Ich hoffe, da macht einer von den "Profis" irgendwann auch noch mal eine Übersicht / ein Tutorial zu. :)

    Die Idee mit der Datenbank hatte ich auch schon, aber kam mir dann doch etwas oversized vor. Wird im Durchschnitt eher bei einer 2-stelligen Anzahl an Einträgen bleiben. Aber die Details gehen sehr in die Breite, würde bei einem Refactoring wahrscheinlich auch 1-2 nested Arrays auflösen und sind dann vielleicht so in der Breite 50 Details je Eintrag.

    Neben "oversized" war mir selber gegenüber auch ein Gegenargument, dass der Umgang mit nested Arrays in Datenbanken wahrscheinlich schwierig ist? Oder sind das dann andere Tabellen? Maps fühlen sich auf jeden Fall etwas näher an dem an, was ich kenne (Arrays) und bin fast nur noch mit AutoIt unterwegs (OOP mit Java nur im Studium) und Hobby-Programmierer, daher beschränkte Erfahrungen ^^

    Datenquellen sind Eingabe über UI und Websiten parsen.


    Der Beispielcode von Mars sieht für mich danach aus, was ich mir in etwa vorgestellt habe, dieses Prinzip der "Fake Klassen"... Und generell ist die Idee von einem Global Enum so einfach und doch so schlau... Das würde mir ja auch mit meinem Array schon so sehr helfen!

    => Wie macht man das denn am geschicktesten? Wenn man mehrere Arrays (und nested Arrays) hat, ist vielleicht ja irgendwann auch unübersichtlich, welches Enum zu welchem Array gehört?

    Nach der Idee stellt sich mir auf jeden Fall die Frage, ob es sich für diesen Fall für mich lohnt, das mit Maps zu refaktorieren, oder ob das ENUM schon mein Hauptproblem mit der Nachvollziehbarkeit löst... Aber bin natürlich auch ein Freund davon, Dinge weiter zu optimieren.

    Vorteil der Map wäre dann ja, dass wenn ich die Nested Arrays auch zu Maps mache, dass ich direkt darauf zugreifen kann, Nachteil, dass ich teilweise die einfachen Funktionen von Arrays verliere. :/ (bis auf Ubound, wenn ich bei Integern bleibe^^)

    Zitat von Mars

    Du müsstest natürlich sämtliche Funktionen dieser "Informationsliste" selbst schreiben. Fast alle davon sollten aber trivial sein.

    Könntest du bitte nochmal erklären, was du damit meinst? Ist ja jetzt keine richtige Klasse, dass ich Getter und Setter brauche?! Welche Funktionen meinst du jetzt? Auslesen und Schreiben würden dann ja auch ohne "Funktion" an den entsprechenden Stellen passieren?!

  • Data Collection-Variables / Maps in AutoIt - Status?

    • aSeCa
    • 19. Februar 2024 um 10:42

    Hey,

    in einem Code habe ich ein sehr komplexes 2D-Array, das Ints, Strings und weitere Arrays enthält. Eig. wäre wahrscheinlich besser als "Klasse" aufgehoben, aber die OOP-Versuche bei Android scheinen ja nicht gefruchtet zu haben.

    Daher habe ich mal geschaut, was es in AutoIt noch so für Möglichkeiten gibt, das zu refaktorieren. Ich habe nur ziemlich alte Posts gefunden. Darunter eine gute Übersicht zu Alternativen zu Arrays, wozu ich dann ergänzend nur noch die "Map" gefunden habe.

    Ich möchte vor allem wegen der Lesbarkeit vom Array weg, weil es so groß geworden ist. So ein assoziativer Datentyp wäre wirklich praktisch.

    Maps hören sich da sehr passend an, zumal man auch Arrays ablegen kann und ich habe ein kleines, aber sehr altes Tutorial dazu gefunden und sogar eine kleine UDF, um den Umgang zu erleichtern (_ArrayDisplay ist echt wichtig zum Debuggen für mich, ein Äquivalent zu haben wäre schon super^^).

    Ich habe auch einen Thread gefunden, wie man Arrays mit Maps verbunden nutzen kann. Aber da werden auch Dinge genutzt, die im alten Tutorial nicht verwendet wurden.

    In den alten Threads ist viel die Rede davon, dass Maps nur Beta sind, das sollte sich ja mittlerweile geändert haben, oder?

    In der Auflistung der Datentypen von AutoIt ist es genannt. Aber wenn ich mir dann im Kontext einzelne Funktionen (z. B. MapKeys) anschaue, ist da noch eine "Experimental"-Warnung.


    Das lässt sich etwas ratlos zurück, wie ich da einsteigen kann. Wie ist denn der Status von Maps? Es gibt einige Neuerungen und ist nicht mehr in der Beta, aber es ist noch nicht "stabil"? Und neuere UDFs/Tutorials dazu gibt es auch nicht?

    Gibt es irgendwo eine Sammlung der genauen (aktuellen) Syntax und aller Funktionen, die es direkt für Maps gibt?

    Ich habe einen kleinen Teil zur Syntax in der Doku gefunden. Ist aber ohne ausführlichere Beispiele auch nur ein Anfang.


    Ich wäre auf jeden Fall dankbar über weiteren Input :).


    Und wie gesagt, mir gehts darum, Informationen zu bestimmten Objekten abzulegen. z. B. Möbelstücke, es kann mehrere geben (das ist die eine Dimension meines Arrays) und dann gibt es etliche Eigenschaften, wie Höhe, Breite, Gewicht, Anzahl der Füße, Name, usw., aber auch weitere nested Arrays, z. B. eine Liste der Teile mit ID / Name / Anzahl.

    Ich habe nicht mal große Anforderungen an die Performance, es wird nur langsam richtig lästig, sich für alles die IDs merken zu müssen: "Ok, brauche die Ersatzteilliste, das war... hmmm... ah, ID 5 und dann der Name steht in der... ah, 3..." Und mein Array ist halt noch viel größer ^^

    Oder sollte man bei Arrays bleiben und dann einfach viele Hilfsfunktionen für genau das Array machen und z. B. die Möbel in einem 1D-Array ablegen (oder einem simplen 2D-Array) und dann einfach Funktionen ala getHeight($aArray[0]), usw. erstellen, die dann einfach nur auf die richtige ID zugreifen?


    Ist etwas viel Text geworden, aber ich dachte, dass ich meine Funde zu Maps auch gleich zusammenfasse / ablege, falls jemand eine ähnliche Frage hat und Input sucht. :)

    Vielen Dank für jede Hilfe!

  • ISN AutoIt Studio

    • aSeCa
    • 10. Februar 2024 um 16:37

    Hey, das Projekt ist wirklich großartig und hilfreich und immer, wenn ich wieder mal was mit AutoIt starte, dann damit :)

    Ich baue grade eine alte GUI um und nutze im Prinzip das erste Mal mit ISN zusammen "Tabs" und frage mich, ob es da eine UX-Funktion gibt, die ich noch übersehen habe oder sonst vllt. als Feedback, wenn du noch weiter Updates machst:

    Wenn man viele Elemente auf dem Tab-Element hat (und natürlich zugeordnet) und dann einen Teil davon zusammen bewegen möchte, dann ist es extrem schwierig die Elemente auszuwählen. Wenn man irgendwo innerhalb des Tab-Elements die Maus drückt, um die Markierung der Elemente zu machen, die man verschieben möchte, dann verschiebt man immer das Tab-Element.

    Die Auswahl via Shift zu erweitern ist ja nicht möglich und ich habe auch keine Option gefunden, das Tab-Element irgendwie zu "sperren".


    Ich habe folgende Workarounds:

    - Gruppen-Element um die Elemente herum (ist teilweise aber aufwendig, hilft manchmal)

    - Die GUI vergrößern oder das Tab-Element verkleinern und dann vom GUI-Hintergrund aus mit der Auswahl starten (klappt nicht immer gut, weil die Auswahl ja nur rechteckig geht und auf volleren GUIs ist das dann schwierig)


    *Edit*

    Wenn ich schon dabei bin, eine Sache, die ich noch cool fände, wäre ein anderes Handling mit der Statusbar. :) Die Trennung mit SetParts wäre in der GUI sehr cool, wenn man das direkt in ISN machen könnte.

    Habe z. B. auch versucht, dann das SetParts im "Extracode" der Statusbar zu machen, aber irgendwie scheint es da noch nicht initialisiert zu sein oder so?! Jedenfalls musste ich es dann an den Anfang meines Codes packen. Das ist überhaupt kein Problem, aber wäre natürlich noch optimierbar, wenn du da Lust zu hast :)


    *Edit2*

    Noch eine Kleinigkeit im GUI-Teil: Immer, wenn ich in einem der weiteren Tabs bin, also nicht dem Haupt-Tab und dann eine Bearbeitung rückgängig mache, dann fliegt man nach der Aktualisierung wieder in den Haupt-Tab. Wenn das Studio sich das merken könnte, wäre das wirklich praktisch! :)


    *Edit3* (^^')
    Warum erlaubst du nur ein Tab pro GUI? Möglich ist ein Tab im Tab ja auf jeden Fall (z. B. siehe hier:https://www.autoitscript.com/forum/topic/195488-tab-in-tab/). Wegen der Komplexität, das in ISN einzubinden?

Spenden

Jeder Euro hilft uns, Euch zu helfen.

Download

AutoIt Tutorial
AutoIt Buch
Onlinehilfe
AutoIt Entwickler
  1. Datenschutzerklärung
  2. Impressum
  3. Shoutbox-Archiv
Community-Software: WoltLab Suite™