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. Kanashius

Beiträge von Kanashius

  • Dateipfad mit Makronamen besetzen

    • Kanashius
    • 24. Juli 2025 um 13:44

    Ich wüsste auf die schnelle keine, aber ich würde nicht generell ersetzen, sondern nur mit/bei dem absoluten Pfad...

    Gerade bei den @UserName Beispiel kann es ja sein, dass jemand woanders auch einen Ordner mit dem Namen hat (z.B. auf dem Desktop), der aber nicht erzetzt werden sollte.
    z.B. wenn du als @UserName=BugFix einen Ordner mit Bildern von einem Ausflug hast, wo jeder seine Bilder teilt, mit C:\users\BugFix\Desktop\AusflugBilder\Kanashius, C:\users\BugFix\Desktop\AusflugBilder\BugFix ,... Dann sollte ja nur das erste BugFix ersetzt werden.

    Aber kommt natürlich drauf an, wofür genau du das machen willst.

  • Android 12 - WLAN priorisieren

    • Kanashius
    • 16. Juni 2025 um 23:56
    Zitat von BugFix

    Ich benötige die alte Internetverbindung noch für meine Telefonie. Die DECT Telefone nutzen die DSL Verbindung der Fritz.Box. Ich schaue mich derzeit nach preislich interessanten SIP Anbietern um, dann kann die alte Internetverbindung weg.

    Ich werde bei uns auch bald auf Wifi SIP Telefone wechseln und hab Grandstream ins Auge gefasst: https://www.grandstream.com/products/ip-vo…y/wifi-cordless

  • Switch GUI

    • Kanashius
    • 12. Juni 2025 um 16:58

    Eine Loop, oder du nutzt den OnEvent mode (https://www.autoitscript.com/autoit3/docs/g…OnEventMode.htm), dann hast du garkeine (GuiGetMsg) Loop mehr.

  • Probs beim Auslesen einer Website

    • Kanashius
    • 11. Juni 2025 um 18:30

    Hmm...

    Ich kann dir gerne anbieten, einmal gemeinsam mit dir draufzuschauen, falls du discord hast und dem AutoIt-Server beitreten möchtest ( https://discord.gg/5DWTpZK3QN ).

    Das würde aber frühestens morgen abend gehen.

    LG Kanashius

  • Probs beim Auslesen einer Website

    • Kanashius
    • 11. Juni 2025 um 09:36

    Hi, das hört sich erstmal gut an.

    Wenn die Daten mit JS zur Laufzeit ins HTML eingefügt werden gibt es im Hintergrund ziemlich sicher eine extra Abfrage die die Daten (vmtl. als Json) zurückgibt, was dann mit JS verarbeitet und ins HTML eingefügt wird.

    Du kannst mal (in Firefox) unter Tools->Browser Tools->Web Developer Tools auswählen und dort auf den Reiter Network gehen. Danach die Seite neuladen.
    Dort dürfte dann eine ganze Liste an Dateien abgerufen werden. Schau in der Tabelle dann unter "Type" nach json (oder generell alles mal durchschauen).
    Wenn du auf einen Eintrag klickst öffnet sich rechts ein Fenster, dort kannst du unter "Response" schauen was auf die Anfrage geantwortet wurde (ggf. den "Raw" toggle umlegen) irgendwo müssten dort die gewollten Daten auftauchen.
    Wenn du den passenden Eintrag gefunden hast: Rechtsklick->Copy Value->Copy as cUrl
    Das Ergebnis kannst du dann hier posten (nachdem du private Infos, die da drin sein könnten, wie host, user, passwort,... durch Beispieldaten ersezt hast (nicht komplett löschen, nur z.B. "SuperPasswort" durch "12345678" oder so ersetzen, wir müssen wissen, ob es gebraucht wird).


    LG Kanashius

  • Probs beim Auslesen einer Website

    • Kanashius
    • 10. Juni 2025 um 14:26

    Hi :)

    Für die Browserautomation gibt es die WebDriver UDF in AutoIt (z.B. https://www.autoitscript.com/wiki/WebDriver).
    Ich hab sie selbst nicht genutzt. SOLVE-SMARTist dort meines wissens nach aktiver. Ich bin gerade eher in python mit selenium (ChromeWebDriver), BeautifulSoup,... unterwegs, wenn du dahin wechseln möchtest könnte ich dir eher weiterhelfen.

    Ansonsten wäre es sinnvoll, sich mal genauer anzuschauen, was auf der Webseite passiert (Web Developer Tools, insbesondere der Network Tab), vllt. wird nur eine bestimmte api abgerufen oder man könnte sich direkt mit einem WebSocket verbinden,... wäre alles einfacher und zuverlässiger als webseiten automatisierung (insbesondere mit Send,...).

    LG, Kanashius

  • _ScreenCapture_Capture() ohne Hilfsdtei verwennden

    • Kanashius
    • 4. Juni 2025 um 13:11

    Ich vermute mal, du willst dir eher die Pixel anschauen und damit weiterarbeiten, und nicht den "String", der nur ein String aus binärdaten ist, die eine enkodierte (bitmap) datei ergibt.

    Wenn du tatsächlich das ganze z.B. als JPG im Abreitsspeicher haben willst, schau dir mal: _GDIPlus_ImageSaveToStream ( $hImage, $pStream, $tEncoder [, $tParams = 0] )

    Ansonsten dürfte dir das hier alle Informationen geben, die du brauchst:

    AutoIt
    #include <ScreenCapture.au3>
    Global $Left=113,$Top=178,$Width=3,$Height=2
    
    
    Local $arPixels = _screenGetPixel(113, 178, 3, 2)
    For $i=0 To UBound($arPixels)-1
    	For $j=0 To UBound($arPixels, 2)-1
    		If $j<>0 Then ConsoleWrite(" : ")
    		ConsoleWrite(StringFormat("%03d %03d %03d %03d", $arPixels[$i][$j][0], $arPixels[$i][$j][1], $arPixels[$i][$j][2], $arPixels[$i][$j][3]))
    	Next
    	ConsoleWrite(@crlf)
    Next
    
    
    Func _screenGetPixel($iLeft, $iTop, $iWidth, $iHeight)
    	_GDIPlus_Startup()
    	Local $hBitmapScreenCapture = _ScreenCapture_Capture("", $iLeft, $iTop, $iLeft + $iWidth, $iTop + $iHeight)
    	Local $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hBitmapScreenCapture)
    	If @error Then Return -1
    	Local $iBitmapWidth = _GDIPlus_ImageGetWidth($hBitmap)
    	Local $iBitmapHeight = _GDIPlus_ImageGetHeight($hBitmap)
    	Local $arPixels[$iBitmapWidth][$iBitmapHeight][4]
    	For $i=0 To $iBitmapWidth-1
    		For $j=0 To $iBitmapHeight-1
    			Local $iColor = _GDIPlus_BitmapGetPixel($hBitmap, $i, $j)
    			$arPixels[$i][$j][0] = BitAND(BitShift($iColor, 24), 0xFF)
    			$arPixels[$i][$j][1] = BitAND(BitShift($iColor, 16), 0xFF)
    			$arPixels[$i][$j][2] = BitAND(BitShift($iColor, 8), 0xFF)
    			$arPixels[$i][$j][3] = BitAND($iColor, 0xFF)
    		Next
    	Next
    	_GDIPlus_BitmapDispose($hBitmap)
    	_WinAPI_DeleteObject($hBitmapScreenCapture)
    	_GDIPlus_Shutdown()
    	Return $arPixels
    EndFunc
    Alles anzeigen

    Die Funktion gibt dir ein Array mit der Farbe jedes Pixels als ARGB ([A, R, G, B]).

    Es dürfte aber deutlich bessere Lösungen geben als das hier.
    Dafür müssten wir aber wissen, wofür du das ganze haben möchtest. ScreenCapture ist vermutlich garnicht das was du brauchst.

  • AutoIt-Hackathon #3 "alte Zeiten"

    • Kanashius
    • 12. Mai 2025 um 17:16
    Zitat von Moombas

    Die tatsächliche Anforderung wäre hier also: "Input date in the format "DD/MM/YYYY HH:MM:SS" "

    Die [] klammern werden tatsächlich normalerweise so angegeben um zu signaliesieren, dass etwas optional ist. Richtig wäre also eher: DD/MM/YYYY[ HH[:MM[:SS]]], da die Zeit nochmal mehrere optionale Felder hat.

    Aber ja, ich bin auch darüber gestolpert... Das erste mal mit DD/MM/YYYY statt YYYY/MM/DD und dann mit dem optionalen,... Irgendwann hab ich mir gedacht, ich ignorier das vorgegebene Muster und ersetze einfach alle Zahlen, dann ist definitiv alles abgedeckt :D

  • AutoIt-Hackathon #3 "alte Zeiten"

    • Kanashius
    • 12. Mai 2025 um 00:45

    Etwas später, aber besser spät als nie ;)

    AutoIt
    ; ================================= entferne alle Leer- und Kommentarzeilen und poste diesen Code-Block im Thread ==================================
    Func _IntegerToRoman($sInteger)
    	Local Static $arPattern=["", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"]
    	Local Static $arNumbers=[["I", "V"], ["X", "L"], ["C", "D"], ["M", ""], ["", ""]]
    	Local $arData = StringSplit($sInteger, "", 3)
    	Local $sResult = ""
    	For $i=0 To UBound($arData)-1 Step 1
    		Local $sSym1 = $arNumbers[UBound($arData)-$i-1][0]
    		Local $sSym2 = $arNumbers[UBound($arData)-$i-1][1]
    		Local $sSym3 = $arNumbers[UBound($arData)-$i][0]
    		$sResult &= StringReplace(StringReplace(StringReplace($arPattern[$arData[$i]], "X", $sSym3), "V", $sSym2), "I", $sSym1)
    	Next
    	Return $sResult
    EndFunc   ;==>_IntegerToRoman
    Func _RomanToInteger($sRoman)
    	Local $arData = StringSplit($sRoman, "", 3), $iResult = 0, $iBefore = 0
    	For $i=0 To UBound($arData)-1 Step 1
    		Local $iAdd = 0
    		Switch $arData[$i]
    			Case "M"
    				$iAdd+=1000
    			Case "D"
    				$iAdd+=500
    			Case "C"
    				$iAdd+=100
    			Case "L"
    				$iAdd+=50
    			Case "X"
    				$iAdd+=10
    			Case "V"
    				$iAdd+=5
    			Case "I"
    				$iAdd+=1
    		EndSwitch
    		If $iBefore<$iAdd Then
    			$iResult-=$iBefore*2
    		EndIf
    		$iResult+=$iAdd
    		$iBefore = $iAdd
    	Next
    	Return $iResult
    EndFunc   ;==>_RomanToInteger
    Func _DateToRoman($sDate) ;Input date in the format "YYYY/MM/DD[ HH:MM:SS]", Output in same date-format with roman sign
    	Local $arDate = StringRegExp($sDate, "\d+", 3)
    	$sDate = StringRegExpReplace($sDate, "\d+", "$")
    	For $i=0 To UBound($arDate)-1
    		$sDate = StringReplace($sDate, "$", _IntegerToRoman($arDate[$i]), 1)
    	Next
    	Return $sDate
    EndFunc   ;==>_DateToRoman
    ; ================================= entferne alle Leer- und Kommentarzeilen und poste diesen Code-Block im Thread ==================================
    Alles anzeigen
  • Datenbank : Teil 1 erstellen einer DB

    • Kanashius
    • 8. Mai 2025 um 16:37

    Hi Alina,

    Ich hab das ganze diesmal auch in eine SQLite Datenbank geschrieben.
    Nur den Tagesverbrauch hab ich weggelassen, da ich den noch nicht wirklich verstanden habe (ist das ein Durchschnitt nach Monatstag? weil es ist kein Datum dabei um einen bestimmten Monat anzugeben).

    Achte auch darauf, dass ich nicht nur die Tabellen angelegt habe, sondern auch einige Views als Beispiel zur Datenabfrage.
    Die Views können wie Tabellen auch in SQL-Abfragen verwendet werden.

    Was das Datum und die Beträge angeht: Lass sie als YYYY-MM-DD und 10.0 in der Datenbank. Das sind die Internationalen Standards, die SQLite automatisch erkennt und verwendet. Ansonsten kann bei den SQLite Operationen (Wie Summe (SUM), Durchschnitt (AVG), Runden (ROUND),...) und den Vergleichen für die Abfragen einiges schief gehen.

    Mach erst alles in SQLite und am Ende baust du dir die Deutsche Variante daraus (In SQL oder AutoIt, je nachdem, wie es besser passt).

    Ein Beispiel für SQLite: SELECT ID, Account, AccountName, Type, TypeName, strftime('%d.%m.%Y %H:%M:%S', Time) as TimeDE, REPLACE(CAST(Change as text), '.', ',') as ChangeDE FROM CombinedBalanceForCalculations

    Edit: Hab die Datenbank noch mit mehr Beispieldaten befüllt (2024/2025) und die Saldo Views überarbeitet, um nicht nur die Veränderung, sondern auch den aktuellen Stand mit auszugeben (z.B. SaldoBefore, SaldoAfter für jeden Monat)

    Dateien

    db_ahl_kanashius.zip 8,09 kB – 490 Downloads
  • array(s) nach daten durchsuchen und zuordnen und damit dann ein neues array anlegen

    • Kanashius
    • 3. Mai 2025 um 15:29


    Hier mal, wie ich die Fragestellungen angehen würde:
    Zu 1.:
    - Liste mit allen Strecken anlegen (mit IDs e.g. StreckenID (nummer zur identifizierung für PC) und Namen (identifizierung für Menschen; muss nicht eindeutig sein))
    - Liste mit Weichen/"Kreuzungen" erstellen (mit eigener WeichenID) und einer Liste mit StreckenIDs, wo man von dort hin kann, keine Ahnung, ob Weichen auch namen brauchen
    - ggf. die Liste mit StreckenIDs in eingehende/ausgehende Strecken unterteilen. Weiche X (WeichenID 1) geht z.b. von Strecke A (StreckenID 1) nach Strecke B (StreckenID 2) oder C (StreckenID 3)
    - Man könnte das ganze dann sogar erweitern mit einer Liste an koordinaten für jede Strecke (Als Pfad, der die Strecke definiert) und das ganze visuell als Grafik abbilden
    - _GDIPlus_GraphicsDrawClosedCurve

    - Die Daten würde ich nicht als INI, sondern als JSON anlegen:
    - https://github.com/Sylvan86/autoit-json-udf dort die JSON.au3 herunterladen
    Das würde dann so aussehen:

    Code
    {
     "Strecken": {
       "1": {
         "name": "A",
         "path": [
           [0, 0],
           [15, 0]
         ]
       },
       "2": {
         "name": "B",
         "path": [
           [5, 5],
           [10, 0]
         ]
       },
       "3": {
         "name": "C",
         "path": [
           [5, 5],
           [5, 10]
         ]
       }
     },
     "Weichen":{
       "1": {
         "in": [1],
         "out": [2,3]
       }
     }
    }
    Alles anzeigen


    Wenn du das mit _JSON_Parse einliest, bekommst du direkt eine Map mit allen Daten.
    Ich würde auch darüber nachdenken, das mit SQL (SQLite) zu lösen und in einer Datenbank abzulegen, das würde aber eine Menge der Logik nach SQL verlegen, was vllt. schwerer für dich wäre.

    Zu 2.:
    - da müsste ich mehr wissen um aktiv zu helfen, bzw. Beispiele zu geben

    Zu 3.:
    - Schau dir mal Endliche Automaten (Finite-state machines) an. Da werden States definiert, und von einem State geht man unter bestimmten bedingungen in einen anderen State über.
    Bei jedem State würde man dann für alle Ampeln den aktuellen status (Ampel Farbe) festlegen

    Zu 4/5.:
    - Ok, da hast du ja schon was :)

    Zu 6.:
    - Da würde ich wirklich in Richtung Datenbank mit SQLite schauen, die sind genau für sowas ausgelegt und ein paar einfache Abfragen sollten zu machen sein.

    Zu 7.: Spaß ist die Hauptsache :)

  • Datenbank : Teil 1 erstellen einer DB

    • Kanashius
    • 27. April 2025 um 20:35

    Hi, ich hab die aktuellsten von der SQLite Website heruntergeladen und umbenannt (https://sqlite.org/download.html) :)

    Ich hab sie mal angehängt.

    Dateien

    accountingAlina.zip 5,77 MB – 567 Downloads
  • Datenbank : Teil 1 erstellen einer DB

    • Kanashius
    • 27. April 2025 um 14:20

    argumentum Nichts mehr, der war mal dafür da, dass ich das BEGIN TRANSACTION;, COMMIT; und ggf. ROLLBACK; nicht immer hinzufüge, sondern nur, wenn $bTransaction True ist (was ich dann bei CREATE TABLE,... ausgeschaltet hatte).

    Ist also nur ein überbleibsel aus der Entwicklungszeit ;)

  • Datenbank : Teil 1 erstellen einer DB

    • Kanashius
    • 26. April 2025 um 23:10

    Ich hab mal was gebastelt ;)

    Zuallererst: Alle deine Infos lassen sich recht kurz zusammenfassen: Geld wird einem Konto hinzugefügt oder abgezogen.

    Alles andere sind Infos, die du aus den Daten herausfinden (berechnen) willst.

    Dafür schaut man sich mal an, welche Daten denn wirklich von dir vorgegeben sind, die nicht allgemein gültig sind oder berechnet werden können.
    Das sind einmal die Konten (accounts) sowie die Transaktionen auf den accounts (ein/auszahlungen).
    Also brauchen wir eine Tabelle für die Accounts und eine für die Transaktionen.
    Transaktionen haben als Info: Zeitpunkt, Die Änderung (+-), eine kurze Beschreibung und einen Verwendungszweck.

    Meine Tabellen sehen also so aus:

    Accounts
    id - primary key, wird automatisch erzeugtname - Name des Kontos
    Bookings
    id - primary key, wird automatisch erzeugtaccount - (id aus Accounts)time - zeit als unixepochchange - (Änderung in cent)short_desc - Kurze Beschreibungpurpose - der Verwendungszweck

    Diese werden in SQLite so angelegt:

    Code
    CREATE TABLE IF NOT EXISTS Bookings(
    	id INTEGER PRIMARY KEY,
    	account INTEGER NOT NULL,
    	time INTEGER DEFAULT (unixepoch()),
    	change INTEGER NOT NULL,
    	short_desc TEXT DEFAULT NULL,
    	purpose TEXT DEFAULT NULL,
    	FOREIGN KEY (account) REFERENCES Accounts (id) ON DELETE CASCADE ON UPDATE NO ACTION
    );
    
    CREATE TABLE IF NOT EXISTS Accounts(
    	id INTEGER PRIMARY KEY,
    	name TEXT NOT NULL
    );
    Alles anzeigen

    Deine Daten können dann mit folgendem hinzugefügt werden:

    Code
    BEGIN TRANSACTION;
    INSERT INTO Bookings (account, time, change, short_desc) VALUES (1, unixepoch("2025-04-25 12:34:56"), 120000, "Einnahmen Lohn1");
    INSERT INTO Bookings (account, change, short_desc) VALUES (1, 25000, "Einnahmen Lohn2");
    INSERT INTO Bookings (account, change, short_desc) VALUES (1, 15000, "Einnahmen WGP");
    INSERT INTO Bookings (account, change, short_desc) VALUES (1, 6000, "Einnahmen LMP VM");
    INSERT INTO Bookings (account, change, short_desc) VALUES (1, 4000, "Einnahmen Extra");
    INSERT INTO Bookings (account, change, short_desc) VALUES (1, -50000, "Ausgaben Miete");
    INSERT INTO Bookings (account, change, short_desc) VALUES (1, -10000, "Ausgaben Strom");
    INSERT INTO Bookings (account, change, short_desc) VALUES (1, -1005, "Ausgaben Bank");
    INSERT INTO Bookings (account, change, short_desc) VALUES (1, -2000, "Ausgaben RuBe");
    INSERT INTO Bookings (account, change, short_desc) VALUES (1, -30000, "Ausgaben LMP");
    INSERT INTO Bookings (account, change, short_desc) VALUES (1, -10000, "Ausgaben DuS");
    INSERT INTO Bookings (account, change, short_desc) VALUES (1, -15000, "Ausgaben frei1");
    INSERT INTO Bookings (account, change, short_desc) VALUES (1, 0, "Ausgaben frei2");
    INSERT INTO Bookings (account, change, short_desc) VALUES (1, 0, "Ausgaben Extra");
    COMMIT;
    
    BEGIN TRANSACTION;
    INSERT INTO Bookings (account, change, short_desc) VALUES (2, 10000, "Eingang Sparbuch");
    INSERT INTO Bookings (account, change, short_desc, purpose) VALUES (2, -7500, "Ausgang Sparbuch", "X, Y, Z");
    COMMIT;
    
    BEGIN TRANSACTION;
    INSERT INTO Accounts (name) VALUES ("Haushaltsbuch"), ("Sparbuch");
    COMMIT;
    Alles anzeigen

    Alles andere wird mit SQL ausgerechnet.
    Für den Startwert, den du angibst kannst du einfach eine weitere Transaktion in Bookings hinzufügen, die den StartWert auf das Konto überweist, e.g. : INSERT INTO Bookings (account, time, change, short_desc) VALUES (1, unixepoch("2000-01-01 00:00:00"), 5000000, "Initiale 50000");


    Und damit du ein Beispiel hast, hab ich mal alle Daten aus deinem Post, die irgendwie errechnet werden können als Ausgabe vorbereitet, du kannst einfach die passenden Zeilen aus/einkommentieren und dir die Abfragen anzeigen lassen.
    Dabei sind zwei Zeilen (41, 46), in denen Daten zum Testen im Zeitraum 2024.01.01 bis 2025.12.28 generiert werden. Besonders das Löschen der alten Tabellen nimmt etwas Zeit ein, also nach dem ersten ausführen am besten die beiden Zeilen auskommentieren.
    _SQLite_ExecCatchErr($hDB, $sSQLReset, False, True)
    _fillWithExampleData($hDB)
    Die SQL-Abfragen sind sehr schnell, wenn das ausführen also mehr als 1 bis 2 Sekunden dauert liegt es daran.

    AutoIt
    #include <SQLite.au3>
    
    Global $sDataFolder = "Data\", $sSQLiteDLL = $sDataFolder&"sqlite3_"&(@AutoItX64?"64":"86")&".dll", $sDatabase = $sDataFolder&"database.sqlite"
    Global $sSQLCreateTableBooking = "" & _
    	"CREATE TABLE IF NOT EXISTS Bookings(" & _
    	  "id INTEGER PRIMARY KEY," & _
    	  "account INTEGER NOT NULL," & _
    	  "time INTEGER DEFAULT (unixepoch())," & _
    	  "change INTEGER NOT NULL," & _
    	  "short_desc TEXT DEFAULT NULL," & _
    	  "purpose TEXT DEFAULT NULL," & _
    	  "FOREIGN KEY (account) REFERENCES Accounts (id) ON DELETE CASCADE ON UPDATE NO ACTION" & _
    	");"
    Global $sSQLCreateTableAccounts = "" & _
    	"CREATE TABLE IF NOT EXISTS Accounts(" & _
    	  "id INTEGER PRIMARY KEY," & _
    	  "name TEXT NOT NULL" & _
    	");"
    Global $sSQLReset = "DROP TABLE IF EXISTS Bookings; DROP TABLE IF EXISTS Accounts;"
    Global $sSQLAllData = "SELECT " & _
    							"b.account, " & _
    							"a.name, " & _
    							"b.time, " & _
    							"datetime(b.time, 'unixepoch') as stime, " & _
    							"strftime('%Y', datetime(b.time, 'unixepoch')) as year, " & _
    							"strftime('%m', datetime(b.time, 'unixepoch')) as month, " & _
    							"strftime('%d', datetime(b.time, 'unixepoch')) as day, " & _
    							"strftime('%w', datetime(b.time, 'unixepoch')) as weekday, " & _
    							"b.change, " & _
    							"b.short_desc, " & _
    							"b.purpose " & _
    						"FROM Bookings b JOIN Accounts a ON b.account=a.id"
    
    _SQLite_Startup($sSQLiteDLL)
    If @error Then MsgBox(16, "Error", 'SQLite could not be loaded. Check, if the file "'&$sSQLiteDLL&'" exists.')
    
    Global $hDB = _SQLite_Open($sDatabase)
    
    ; For Debugging to remove old data
    _SQLite_ExecCatchErr($hDB, $sSQLReset, False, True)
    
    _SQLite_ExecCatchErr($hDB, $sSQLCreateTableBooking, False, True)
    _SQLite_ExecCatchErr($hDB, $sSQLCreateTableAccounts, False, True)
    
    _fillWithExampleData($hDB)
    
    Local $arColumns, $arData
    
    ; Output Table Accounts
    $arData = _SQLite_GetAllCatchErr($hDB, "SELECT * From Accounts", $arColumns)
    _printData($arData, $arColumns, "Table Accounts")
    
    ; Output Table Bookings
    $arData = _SQLite_GetAllCatchErr($hDB, "SELECT * From Bookings", $arColumns)
    _printData($arData, $arColumns, "Table Bookings")
    
    ; Output everything with extra data
    ; $arData = _SQLite_GetAllCatchErr($hDB, $sSQLAllData, $arColumns)
    ; _printData($arData, $arColumns, "All data with extra infos for further processing")
    
    
    ; output change by month
    ; $arData = _SQLite_GetAllCatchErr($hDB, "SELECT name, year, month, cast(SUM(change) as float)/100 as change FROM ("&$sSQLAllData&") GROUP BY name, month, year ORDER BY name, year, month", $arColumns)
    ; _printData($arData, $arColumns, "Change by Month-Year")
    
    ; output change by year
    ; $arData = _SQLite_GetAllCatchErr($hDB, "SELECT name, year, cast(SUM(change) as float)/100 as change FROM ("&$sSQLAllData&") GROUP BY name, year ORDER BY name, year", $arColumns)
    ; _printData($arData, $arColumns, "Change by Year")
    
    ; output change by half year
    ; $arData = _SQLite_GetAllCatchErr($hDB, "SELECT name, year, month/6+1 as halfyear, cast(SUM(change) as float)/100 as change FROM ("&$sSQLAllData&") GROUP BY name, year, (month-1)/6 ORDER BY name, year, halfyear", $arColumns)
    ; _printData($arData, $arColumns, "Change by Half Year")
    
    ; output change by quarter
    ; $arData = _SQLite_GetAllCatchErr($hDB, "SELECT name, year, month/3+1 as quarter, cast(SUM(change) as float)/100 as change FROM ("&$sSQLAllData&") GROUP BY name, year, (month-1)/3 ORDER BY name, year, quarter", $arColumns)
    ; _printData($arData, $arColumns, "Change by Quarter")
    
    ; output change by third
    ; $arData = _SQLite_GetAllCatchErr($hDB, "SELECT name, year, month/4+1 as third, cast(SUM(change) as float)/100 as change FROM ("&$sSQLAllData&") GROUP BY name, year, (month-1)/4 ORDER BY name, year, third", $arColumns)
    ; _printData($arData, $arColumns, "Change by Year/3")
    
    ; output change by day
    Global $sSQLChangeByDay = "SELECT name, year, month, day, cast(SUM(change) as float)/100 as change FROM ("&$sSQLAllData&") GROUP BY name, year, month, day ORDER BY name, year, month, day"
    ; $arData = _SQLite_GetAllCatchErr($hDB, "SELECT name, year, month, day, cast(SUM(change) as float)/100 as change FROM ("&$sSQLAllData&") GROUP BY name, year, month, day ORDER BY name, year, month, day", $arColumns)
    ; _printData($arData, $arColumns, "Change by Day")
    
    ; output spending avarage by day
    ; $arData = _SQLite_GetAllCatchErr($hDB, "SELECT name, year, AVG(change) as average FROM ("&$sSQLChangeByDay&") GROUP BY name, year ORDER BY name, year", $arColumns)
    ; _printData($arData, $arColumns, "Average change by day")
    
    ; output spending avarage by week
    ; $arData = _SQLite_GetAllCatchErr($hDB, "SELECT name, year, AVG(change)*7 as average FROM ("&$sSQLChangeByDay&") GROUP BY name, year ORDER BY name, year", $arColumns)
    ; _printData($arData, $arColumns, "Average change by week")
    
    ; output spending avarage by weekday
    ; $arData = _SQLite_GetAllCatchErr($hDB, "SELECT name, year, weekday, cast(AVG(change) as float)/100 as average FROM ("&$sSQLAllData&") GROUP BY name, year, weekday ORDER BY name, year, weekday", $arColumns)
    ; _printData($arData, $arColumns, "Average change by day")
    
    ; output saldo
    ; $arData = _SQLite_GetAllCatchErr($hDB, "SELECT a.name, cast(SUM(b.change) as float)/100 as saldo FROM Bookings b JOIN Accounts a ON b.account=a.id GROUP BY a.name", $arColumns)
    ; _printData($arData, $arColumns, "Saldo")
    
    ; output saldo until specific datetime
    ; $arData = _SQLite_GetAllCatchErr($hDB, "SELECT a.name, cast(SUM(b.change) as float)/100 as saldo FROM Bookings b JOIN Accounts a ON b.account=a.id WHERE b.time<unixepoch('2025-01-01 00:00:00') GROUP BY a.name", $arColumns)
    ; _printData($arData, $arColumns, "Saldo at 2025-01-01 00-00-00")
    
    ; output change by quarter for year 2025
    ; $arData = _SQLite_GetAllCatchErr($hDB, "SELECT name, year, month/3+1 as quarter, cast(SUM(change) as float)/100 as change FROM ("&$sSQLAllData&") WHERE year='2025' GROUP BY name, year, (month-1)/3 ORDER BY name, year, quarter", $arColumns)
    ; _printData($arData, $arColumns, "Change by Quarter (2025)")
    
    Func _exit()
    	_SQLite_Close($hDB)
    	_SQLite_Shutdown()
    	Exit
    EndFunc
    
    Func _SQLite_ExecCatchErr($hDB, $sSql, $bTransaction = True, $bFatal = False)
    	_SQLite_Exec($hDB, 'BEGIN TRANSACTION;'&$sSql&'COMMIT;')
    	If @error Then
    		_SQLite_Exec($hDB, "ROLLBACK;")
    		MsgBox(16, "SQLite Error", "Error Code: " & _SQLite_ErrCode() & @CRLF & "Error Message: " & _SQLite_ErrMsg() & "Executing """&$sSql&"""")
    		If $bFatal Then _exit()
    	EndIf
    EndFunc
    
    Func _SQLite_GetDataCatchErr($hDB, $sSql)
    	Local $arColumns
    	Return _SQLite_GetAllCatchErr($hDB, $sSql, $arColumns)
    EndFunc
    
    Func _SQLite_GetAllCatchErr($hDB, $sSql, ByRef $arColumns)
    	Local $arResult, $iRows
    	_SQLite_GetTableData2D($hDB, $sSql, $arResult, $iRows, $arColumns)
    	If @error Then
    		MsgBox(16, "SQLite Error", "Error Code: " & _SQLite_ErrCode() & @CRLF & "Error Message: " & _SQLite_ErrMsg() & "Executing """&$sSql&"""")
    		Local $arResult[0][0]
    		Return SetError(1, 0, $arResult)
    	EndIf
    	Return $arResult
    EndFunc
    
    Func _printData(ByRef $arData, ByRef $arColumns, $sTitle = Default)
    	If Not IsArray($arData) Or Not IsArray($arColumns) Then Return -1
    	If UBound($arData,0)<>2 Then Return -1
    	Local $arColWidth[UBound($arData, 2)]
    	For $i=0 To UBound($arColumns)-1 Step 1
    		If StringLen($arColumns[$i])>$arColWidth[$i] Then $arColWidth[$i] = StringLen($arColumns[$i])
    	Next
    	For $j=0 To UBound($arData, 2)-1 Step 1
    		For $i=0 To UBound($arData, 1)-1 Step 1
    			Local $arMatch = StringRegExp($arData[$i][$j], "(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})", 1)
    			If Not @error Then
    				$arData[$i][$j] = $arMatch[0]&"-"&$arMatch[1]&"-"&$arMatch[2]&" "&$arMatch[3]&"-"&$arMatch[4]&"-"&$arMatch[5]
    			EndIf
    			If StringLen($arData[$i][$j])>$arColWidth[$j] Then $arColWidth[$j] = StringLen($arData[$i][$j])
    		Next
    	Next
    	Local $arSeps[UBound($arColWidth)], $iMaxLength = 0
    	For $i=0 To UBound($arColWidth)-1 Step 1
    		$iMaxLength+=$arColWidth[$i]+3
    	Next
    	Local $iAdd = 0
    	If $iMaxLength<StringLen($sTitle) Then $iAdd = Int((StringLen($sTitle)-$iMaxLength+4)/UBound($arColWidth))+(Mod((StringLen($sTitle)-$iMaxLength)+4, UBound($arColWidth))>0?1:0)
    	For $i=0 To UBound($arColWidth)-1 Step 1
    		$arColWidth[$i] += $iAdd
    	Next
    	For $i=0 To UBound($arColWidth)-1 Step 1
    		For $j=0 To $arColWidth[$i]+1 Step 1
    			$arSeps[$i] &= "-"
    		Next
    	Next
    	If $sTitle<>Default Then
    		ConsoleWrite("+")
    		For $i=0 To UBound($arSeps)-1 Step 1
    			ConsoleWrite($arSeps[$i])
    			If $i<UBound($arSeps)-1 Then ConsoleWrite("-")
    		Next
    		ConsoleWrite("+"&@crlf)
    		Local $iTitleSpace = Int(($iMaxLength-3-StringLen($sTitle))/2)
    		If $iTitleSpace<0 Then $iTitleSpace=0
    		Local $iExtra = 0
    		If Mod(($iMaxLength-3-StringLen($sTitle))/2, 2)<>0 Then $iExtra = 1
    		ConsoleWrite(StringFormat("| %"&$iTitleSpace&"s%s%"&$iTitleSpace+$iExtra&"s |", "", $sTitle, "")&@crlf)
    	EndIf
    	For $i=0 To UBound($arSeps)-1 Step 1
    		ConsoleWrite("+"&$arSeps[$i])
    	Next
    	ConsoleWrite("+"&@crlf)
    	For $i=0 To UBound($arColumns)-1 Step 1
    		ConsoleWrite(StringFormat("| %-"&$arColWidth[$i]&"s ", StringUpper($arColumns[$i])))
    	Next
    	ConsoleWrite("| "&@crlf)
    	ConsoleWrite("+")
    	For $i=0 To UBound($arSeps)-1 Step 1
    		ConsoleWrite($arSeps[$i])
    		If $i<UBound($arSeps)-1 Then ConsoleWrite("-")
    	Next
    	ConsoleWrite("+"&@crlf)
    	For $i=0 To UBound($arData, 1)-1 Step 1
    		For $j=0 To UBound($arData, 2)-1 Step 1
    			ConsoleWrite(StringFormat("| %-"&$arColWidth[$j]&"s ", $arData[$i][$j]))
    		Next
    		ConsoleWrite("| "&@crlf)
    	Next
    	For $i=0 To UBound($arSeps)-1 Step 1
    		ConsoleWrite("+"&$arSeps[$i])
    	Next
    	ConsoleWrite("+"&@crlf)
    EndFunc
    
    Func _fillWithExampleData($hDB)
    	_SQLite_ExecCatchErr($hDB, 'INSERT INTO Accounts (name) VALUES ("Haushaltsbuch"), ("Sparbuch");')
    	#cs
    	_SQLite_ExecCatchErr($hDB, '' & _
    			'INSERT INTO Bookings (account, time, change, short_desc) VALUES (1, unixepoch("2025-04-25 12:34:56"), 120000, "Einnahmen Lohn1");' & _
    			'INSERT INTO Bookings (account, change, short_desc) VALUES (1, 25000, "Einnahmen Lohn2");' & _
    			'INSERT INTO Bookings (account, change, short_desc) VALUES (1, 15000, "Einnahmen WGP");' & _
    			'INSERT INTO Bookings (account, change, short_desc) VALUES (1, 6000, "Einnahmen LMP VM");' & _
    			'INSERT INTO Bookings (account, change, short_desc) VALUES (1, 4000, "Einnahmen Extra");' & _
    			'INSERT INTO Bookings (account, change, short_desc) VALUES (1, -50000, "Ausgaben Miete");' & _
    			'INSERT INTO Bookings (account, change, short_desc) VALUES (1, -10000, "Ausgaben Strom");' & _
    			'INSERT INTO Bookings (account, change, short_desc) VALUES (1, -1005, "Ausgaben Bank");' & _
    			'INSERT INTO Bookings (account, change, short_desc) VALUES (1, -2000, "Ausgaben RuBe");' & _
    			'INSERT INTO Bookings (account, change, short_desc) VALUES (1, -30000, "Ausgaben LMP");' & _
    			'INSERT INTO Bookings (account, change, short_desc) VALUES (1, -10000, "Ausgaben DuS");' & _
    			'INSERT INTO Bookings (account, change, short_desc) VALUES (1, -15000, "Ausgaben frei1");' & _
    			'INSERT INTO Bookings (account, change, short_desc) VALUES (1, 0, "Ausgaben frei2");' & _
    			'INSERT INTO Bookings (account, change, short_desc) VALUES (1, 0, "Ausgaben Extra");' & _
    		'')
    	_SQLite_ExecCatchErr($hDB, '' & _
    			'INSERT INTO Bookings (account, change, short_desc) VALUES (2, 10000, "Eingang Sparbuch");' & _
    			'INSERT INTO Bookings (account, change, short_desc, purpose) VALUES (2, -7500, "Ausgang Sparbuch", "X, Y, Z");' & _
    		'')
    	#ce
    	; generate some example data for 2024+2025 (complete years)
    	Local $arData = [ _
    		[1, 120000, "Einnahmn Lohn1", ""], _
    		[1, 25000, "Einnahmen Lohn2", ""], _
    		[1, 15000, "Einnahmen WGP", ""], _
    		[1, 6000, "Einnahmen LMP VM", ""], _
    		[1, 4000, "Einnahmen Extra", ""], _
    		[1, -50000, "Ausgaben Miete", ""], _
    		[1, -10000, "Ausgaben Strom", ""], _
    		[1, -1005, "Ausgaben Bank", ""], _
    		[1, -2000, "Ausgaben RuBe", ""], _
    		[1, -30000, "Ausgaben LMP", ""], _
    		[1, -10000, "Ausgaben DuS", ""], _
    		[1, -15000, "Ausgaben frei1", ""], _
    		[1, 0, "Ausgaben frei2", ""], _
    		[1, 0, "Ausgaben Extra", ""], _
    		[2, 10000, "Eingang Sparbuch", ""], _
    		[2, -7500, "Ausgang Sparbuch", "X, Y, Z"] _
    	]
    	For $iYear=2024 To 2025 Step 1
    		For $iMonth=1 To 12 Step 1
    			Local $sSql = ""
    			For $i=0 To UBound($arData)-1 Step 1
    				Local $iDay = Random(1, 28, 1)
    				Local $sDate = StringFormat("%04d-%02d-%02d %02d:%02d:%02d", $iYear, $iMonth, $iDay, 12, 30, 00)
    				Local $iMultiplier = Random(0.6, 1)
    				If $arData[$i][3]="" Then
    					$sSql &= StringFormat('INSERT INTO Bookings (account, time, change, short_desc) VALUES (%d, unixepoch("%s"), %d, "%s");', $arData[$i][0], $sDate, $arData[$i][1]*$iMultiplier, $arData[$i][2])
    				Else
    					$sSql &= StringFormat('INSERT INTO Bookings (account, time, change, short_desc, purpose) VALUES (%d, unixepoch("%s"), %d, "%s", "%s");', $arData[$i][0], $sDate, $arData[$i][1]*$iMultiplier, $arData[$i][2], $arData[$i][3])
    				EndIf
    			Next
    			_SQLite_ExecCatchErr($hDB, $sSql)
    		Next
    	Next
    EndFunc
    Alles anzeigen

    Ich hoffe das hilft dir weiter, bzw. gibt dir einen kleinen Anstoß.

  • ConsoleWrite() und Fehlermeldungen darin unter bestimmten Bedingungen

    • Kanashius
    • 26. April 2025 um 15:36
    AutoIt
    For $a = 0 To 144
        For $b = 0 To 144
            ConsoleWrite("Dice: " & $numbers2[$b] & " ----------> " & " Number: " & $numbers1[$b] &@CRLF)
        Next
    Next
    ; 0-144 sind 145 Durchläufe, was ein Index zu groß ist, deshalb die Fehlermeldung "Array variable has incorrect number of subscripts"
    
    For $a = 0 To $numbers2
        For $b = 0 To $numbers1
            ConsoleWrite("Dice: " & $numbers2[$b] & " ----------> " & " Number: " & $numbers1[$b] &@CRLF)
        Next
    Next
    ; $numbers2 und $numbers1 sind Arrays. In den meisten Sprachen fliegt dir das um die Ohren, weil es keine Zahlen sind, in AutoIt passiert das nicht,
    ; stattdessen wird versucht, sie in eine Zahl umzuwandeln. Das geht bei Arrays nicht, also wird 0 zurückgegeben.
    ; For $a = 0 To $numbers2 ist das gleiche wie For $a=0 to 0 => Es läuft genau einmal mit $a=0
    
    For $a = 0 To UBound($numbers2) - 1
        For $b = 0 To UBound($numbers1) - 1
            ConsoleWrite("Dice: " & $numbers2[$b] & " ----------> " & " Number: " & $numbers1[$b] &@CRLF)
        Next
    Next
    ; Es ist alles richtig und es passiert genau das, was dort geschrieben steht, ohne seltsame nebeneffekte.
    ; Du läufts von 0 bis UBound($numbers2)-1 => 0 bis 143 und führst alles in der Schleife 144x aus.
    ; Da du in der Schleife eine weitere Schleife hast, die auch von 0 bis 143 geht und diese für jeden der 144x durchlaufe einmal durchlaufen wird
    ; kommst du auf 144x144 durchläufe der Zeile => ConsoleWrite("Dice: " & $numbers2[$b] & " ----------> " & " Number: " & $numbers1[$b] &@CRLF)
    ; Hier ist es kein Fehler in AutoIt oder beim Programmieren, sondern ein Logik-Fehler, was genau du umsetzen willst
    
    For $a = 0 To 143
        For $b = 0 To 143
            ConsoleWrite("Dice: " & $numbers2[$b] & " ----------> " & " Number: " & $numbers1[$b] &@CRLF)
        Next
    Next
    ; Selbe wie vorher, nur dass du die Größe der Arrays nicht verändern darfst
    
    For $a = 0 To $numbers2[$a]
        For $b = 0 To $numbers1[$b]
            ConsoleWrite("Dice: " & $numbers2[$b] & " ----------> " & " Number: " & $numbers1[$b] &@CRLF)
        Next
    Next
    ; Du gehst von $a=0 bis zu dem Wert, der in $numbers2[$a] steht, also in $numbers2[0] (Im ersten durchlauf)
    ; Da du die Arrays durchmischt, wird dort jedesmal eine andere Zahl stehen, welche auch immer dort hingemischt wurde...
    ; Wenn das zufällig 144 ist, wird das ganze mit ner Fehlermeldung abstürzen
    ; Das ganze ergibt also nicht mal Ansatzweise einen Sinn
    ; Selbes auch für das Beispiel, wo du nochmal 1 abziehst...
    
    
    
    ; Ich bin mir nicht sicher, was genau du machen willst, aber ich hab mal zwei sachen gebastelt, die vermutlich in die Richtung gehen...
    Local $arData = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    Local $arData2 = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
    
    ConsoleWrite("--------------------------"&@crlf)
    For $i=0 To UBound($arData)-1 Step 1
    	ConsoleWrite($i&": "&$arData[$i]&" - "&$arData2[$i]&@crlf)
    Next
    
    ConsoleWrite("--------------------------"&@crlf)
    For $i=0 To 100
    	Local $iRandom = Random(0, UBound($arData)-1, 1)
    	ConsoleWrite($iRandom&": "&$arData[$iRandom]&@crlf)
    Next
    Alles anzeigen
  • AutoIt-Hackathon #2 CypherEnigma

    • Kanashius
    • 22. April 2025 um 16:16
    AutoIt
    Func _CypherEnigma($sString, $nKlein, $nGross, $nSonder, $nExtra)
    	Local $arLetters = StringToASCIIArray($sString)
    	Local $iExtra = $nExtra
    	For $i=0 To UBound($arLetters)-1 Step 1
    		Local $iCode = $arLetters[$i]
    		If $iCode>64 And $iCode<91 Then
    			$iCode = 65 + Mod($iCode + $nGross + $iExtra - 65, 26)
    		ElseIf $iCode>96 And $iCode<123 Then
    			$iCode = 97 + Mod($iCode + $nKlein + $iExtra - 97, 26)
    		ElseIf $iCode>31 And $iCode<127 Then
    			$iCode -= 32
    			If $iCode>32 Then $iCode-=26
    			If $iCode>38 Then $iCode-=26
    			$iCode = Mod($iCode + $nSonder + $iExtra, 43) + 32
    			If $iCode>64 Then $iCode+=26
    			If $iCode>96 Then $iCode+=26
    		EndIf
    		$arLetters[$i] = $iCode
    		$iExtra += $nExtra
    	Next
    	Return StringFromASCIIArray($arLetters)
    EndFunc   ;==>_CypherEnigma
    Alles anzeigen
  • map fuer ein magisches quadrat und dessen aufloesung

    • Kanashius
    • 19. April 2025 um 22:25

    Ich fand Magic Squares ganz interessant, wollte die aber nicht in einer Ini abspeichern, sondern selbst generieren.
    Bis ich das fertig hatte, hat in der Zwischenzeit Schnuffel schon gepostet, deshalb geh ich auf dein Script mal nicht weiter ein.
    Stattdessen hab ich noch eine Gui dazugebastelt, in der man einen Text eingeben kann und sowohl mit Magic Square verschlüsseln als auch entschlüsseln kann.
    Das ganze arbeitet dabei mit einem Füll-Zeichen, wenn die Anzahl an Text nicht ein ganzes Magic Square füllt.
    Das Trenn-Zeichen kann dabei auch geändert werden. (Wenn es leer gelassen wird, wird jeder Buchstabe einzeln vertauscht, was für ein richtiges durcheinander sorgt :D)

    Vielleicht hat ja noch jemand Spaß daran :)

    AutoIt
    Global $sExampleText = "dieses kleine aber durchaus feine AutoIT test script soll einen total konfus"&@crlf& _
    						"gewirbelten satz durch eine ini map wieder in einen lesbaren string bzw."&@crlf& _
    						"array verwandeln. es basiert auf dem prinzip eines zwoelf mal zwoelf rasters"&@crlf& _
    						"und stellt ein magisches quadrat dar. es ist das einfachste bzw. simpelste"&@crlf& _
    						"magische quadrat was es im internet zu finden gibt. es besteht also"&@crlf& _
    						"aus zwoelf worten in jeweils zwoelf reihen und zwoelf worten in jeweils"&@crlf& _
    						"zwoelf spalten. somit sind es dann insgesamt 144 worte. ich habe das"&@crlf& _
    						"ganze vorher in libre office calc ausrechen lassen wo welches wort stehen"&@crlf& _
    						"muss um dann eine ini datei zu schreiben wo das richtige wort"&@crlf& _
    						"aus dem text eigentlich stehen muss damit es auch einen sinn ergibt."&@crlf& _
    						"AutoIT hilft dann dabei die ganzen woerter zu sortieren. ich finde das"&@crlf& _
    						"immer so toll kleine scripte zu testen und ihr hoffentlich dann auch!"
    
    ; Print a square to console
    ; Local $arSquare = _calcMagicSquare(12)
    ; _printMagicSquare($arSquare)
    
    ; checking if the square generation works:
    ; For $i=0 To 100 Step 1
    ;	 Local $arSquare = _calcMagicSquare($i)
    ;	 If (Not _checkAllOneValue(_getArrayLineSums($arSquare))) Or (Not _checkAllOneValue(_getArrayLineSums($arSquare, True))) Then ConsoleWrite("Magic Square for "&$i&" was wrong."&@crlf)
    ; Next
    
    ; open encrypt/decrypt gui
    _openGui()
    
    Func _openGui()
    	Local $iWidth = 1200, $iHeight=800, $iSpace = 10, $iCtrlHeight=25
    	Local $hGui = GUICreate("Text scrambler", $iWidth, $iHeight)
    	Local $iEditWidth = ($iWidth-($iSpace*3))/2, $iEditHeight = $iHeight-$iSpace*4-$iCtrlHeight*2
    	Local $iWidth4th = ($iWidth-$iSpace*5)/4
    	GUICtrlCreateLabel("Delimeter: ", $iSpace, $iSpace, $iWidth4th, $iCtrlHeight)
    	Local $idInputDelimeter = GUICtrlCreateInput(" ", $iSpace*2+$iWidth4th, $iSpace, $iWidth4th, $iCtrlHeight)
    	GUICtrlCreateLabel("Filler: ", $iSpace*3+$iWidth4th*2, $iSpace, $iWidth4th, $iCtrlHeight)
    	Local $idInputFiller = GUICtrlCreateInput(".", $iSpace*4+$iWidth4th*3, $iSpace, $iWidth4th, $iCtrlHeight)
    	Local $idEditClearText = GUICtrlCreateEdit($sExampleText, $iSpace, $iSpace*2+$iCtrlHeight, $iEditWidth, $iEditHeight)
    	Local $idButtonEncrypt = GUICtrlCreateButton("Encrypt >>", $iSpace, $iHeight-$iSpace-$iCtrlHeight, $iEditWidth, $iCtrlHeight)
    	Local $idEditEncrypted = GUICtrlCreateEdit("", $iSpace*2+$iEditWidth, $iSpace*2+$iCtrlHeight, $iEditWidth, $iEditHeight)
    	Local $idButtonDecrypt = GUICtrlCreateButton("<< Decrypt", $iSpace*2+$iEditWidth, $iHeight-$iSpace-$iCtrlHeight, $iEditWidth, $iCtrlHeight)
    	GUISetState(@SW_SHOW, $hGui)
    	Local $iMsg
    	While 1
    		$iMsg = GUIGetMsg()
    		Switch $iMsg
    			Case -3
    				Exit
    			Case $idButtonEncrypt
    				Local $sDelimeter = GUICtrlRead($idInputDelimeter)
    				Local $sFiller = GUICtrlRead($idInputFiller)
    				Local $sEncrypted = _cryptSquare(GUICtrlRead($idEditClearText), True, $sDelimeter, $sFiller)
    				GUICtrlSetData($idEditEncrypted, $sEncrypted)
    			Case $idButtonDecrypt
    				Local $sDelimeter = GUICtrlRead($idInputDelimeter)
    				Local $sFiller = GUICtrlRead($idInputFiller)
    				Local $sEncrypted = _cryptSquare(GUICtrlRead($idEditEncrypted), False, $sDelimeter, $sFiller)
    				If @error Then MsgBox(16, "Error", "Input length does not match any magic square size.")
    				GUICtrlSetData($idEditClearText, $sEncrypted)
    		EndSwitch
    	WEnd
    EndFunc
    
    Func _cryptSquare($sText, $bEncrypt = True, $sDelimeter=" ", $sFiller = ".")
    	Local $arParts = StringSplit($sText, $sDelimeter, BitOR(1,2))
    	Local $iSize = Sqrt(UBound($arParts))
    	If Mod($iSize, 1)<>0 Then $iSize = Int($iSize+1)
    	If $iSize=2 Then $iSize+=1
    	Local $arSquare = _calcMagicSquare($iSize)
    	If $bEncrypt Then
    		Local $sResult = ""
    		For $i=0 To UBound($arSquare)-1 Step 1
    			For $j=0 To UBound($arSquare)-1 Step 1
    				Local $iVal = $arSquare[$i][$j]
    				If $iVal>UBound($arParts) Then
    					$sResult &= $sFiller
    				Else
    					$sResult &= $arParts[$arSquare[$i][$j]-1]
    				EndIf
    				If $i<UBound($arSquare)-1 Or $j<UBound($arSquare)-1 Then $sResult &= $sDelimeter
    			Next
    		Next
    		Return $sResult
    	Else
    		Local $arResult[UBound($arParts)], $iCount = 0
    		For $i=0 To UBound($arSquare)-1 Step 1
    			For $j=0 To UBound($arSquare)-1 Step 1
    				Local $iIndex = $arSquare[$i][$j]-1
    				If $iCount>UBound($arParts)-1 Then Return SetError(1, 0, -1)
    				If $iIndex<UBound($arResult) Then $arResult[$iIndex] = $arParts[$iCount]
    				$iCount+=1
    			Next
    		Next
    		Local $sResult = ""
    		For $i=0 To UBound($arResult)-1 Step 1
    			$sResult &= $arResult[$i]
    			If $i<UBound($arResult)-1 Then $sResult&=$sDelimeter
    		Next
    		Return $sResult
    	EndIf
    EndFunc
    
    Func _checkAllOneValue(ByRef $arArray)
    	Local $iVal = $arArray[0]
    	For $i=0 To UBound($arArray)-1 Step 1
    		If $arArray[$i]<>$iVal Then Return False
    	Next
    	Return True
    EndFunc
    
    Func _printMagicSquare(ByRef $arSquare, $bShowInfo = True)
    	Local $arSumRight, $arSumBottom
    	If $bShowInfo Then
    		$arSumRight = _getArrayLineSums($arSquare)
    		$arSumBottom = _getArrayLineSums($arSquare, True)
    	EndIf
    	Local $iSize = UBound($arSquare)
    	Local $iMaxLength = StringLen(String($iSize*$iSize))
    	If $bShowInfo Then
    		If StringLen($arSumBottom[UBound($arSumBottom)-1])+1>$iMaxLength Then $iMaxLength=StringLen($arSumBottom[UBound($arSumBottom)-1])+1
    	EndIf
    	Local $sNumberFormat = "%"&$iMaxLength&"d|"
    	For $x=0 To $iSize-1 Step 1
    		_printLine($iSize, $iMaxLength)
    		ConsoleWrite("|")
    		For $y=0 To $iSize-1 Step 1
    			ConsoleWrite(StringFormat($sNumberFormat, $arSquare[$x][$y]))
    		Next
    		If $bShowInfo Then ConsoleWrite(" ="&$arSumRight[$x])
    		ConsoleWrite(@crlf)
    	Next
    	If $bShowInfo Then
    		_printLine($iSize, $iMaxLength)
    		For $x=0 To $iSize-1 Step 1
    			ConsoleWrite(StringFormat("%"&$iMaxLength+1&"s", "="&$arSumBottom[$x]))
    		Next
    		ConsoleWrite(@crlf)
    	EndIf
    EndFunc
    
    ; Last item contains the max sum
    Func _getArrayLineSums(ByRef $arSquare, $bRow=False)
    	Local $iSize = UBound($arSquare)
    	Local $arSum[$iSize+1]
    	For $i=0 To $iSize-1 Step 1
    		Local $iSum = 0
    		For $j=0 To $iSize-1 Step 1
    			If $bRow Then
    				$iSum += $arSquare[$j][$i]
    			Else
    				$iSum += $arSquare[$i][$j]
    			EndIf
    		Next
    		$arSum[$i] = $iSum
    		If $iSum>$arSum[$iSize] Then $arSum[$iSize] = $iSum
    	Next
    	Return $arSum
    EndFunc
    
    Func _printLine($iSegmentCount, $iSegmentLength)
    	Local $sSep = ""
    	For $x=0 To $iSegmentLength-1 Step 1
    		$sSep&="-"
    	Next
    	ConsoleWrite("+")
    	For $y=0 To $iSegmentCount-1 Step 1
    		ConsoleWrite($sSep&"+")
    	Next
    	ConsoleWrite(@crlf)
    EndFunc
    
    ; https://www.iupindia.in/910/IJCM_Magic_Square_Construction_Algorithms34.pdf
    Func _calcMagicSquare($iSize)
    	If $iSize=2 Then Return SetError(1, -1, -1) ; not possible for $iSize=2
    	Local $arSquare[$iSize][$iSize]
    	If $iSize=4 Then
    		Local $arTmp = [[1, 15, 14, 4], [12, 6, 7, 9], [8, 10, 11, 5], [13, 3, 2, 16]] ; algorithm used only once, so why implement it
    		Return $arTmp
    	ElseIf Mod($iSize, 2)=0 Then ; size is even
    		If Mod($iSize, 4)=2 Then
    			Local $iMatMax = ($iSize*$iSize)/4, $iMatSize = $iSize/2
    			Local $arM1 = _calcMagicSquare($iSize/2)
    			; initial square
    			For $i=0 To 1 Step 1
    				For $j=0 To 1 Step 1
    					Local $iAdd = 0
    					If $i=1 And $j=0 Then $iAdd = $iMatMax*3
    					If $i=0 And $j=1 Then $iAdd = $iMatMax*2
    					If $i=1 And $j=1 Then $iAdd = $iMatMax
    					For $x=0 To $iMatSize-1 Step 1
    						For $y=0 To $iMatSize-1 Step 1
    							$arSquare[$x+($i*$iMatSize)][$y+($j*$iMatSize)] = $arM1[$x][$y] + $iAdd
    						Next
    					Next
    				Next
    			Next
    			; swapping around
    			Local $iMatSizeHalf = Int($iMatSize/2)
    			For $x=0 To $iMatSizeHalf-1
    				For $y=0 To $iMatSizeHalf-1
    					_swap($arSquare, $x, $y, $x+$iMatSize, $y)
    				Next
    			Next
    			For $x=$iMatSizeHalf+1 To $iMatSize-1 Step 1
    				For $y=0 To $iMatSizeHalf-1 Step 1
    					_swap($arSquare, $x, $y, $x+$iMatSize, $y)
    				Next
    			Next
    			Local $x=$iMatSizeHalf
    			For $y=1 To $iMatSizeHalf Step 1
    				_swap($arSquare, $x, $y, $x+$iMatSize, $y)
    			Next
    			For $x=0 To $iMatSize-1 Step 1
    				For $y=($iMatSize-$iMatSizeHalf)+1 To $iMatSize-1 Step 1
    					_swap($arSquare, $x, $y+$iMatSize, $x+$iMatSize, $y+$iMatSize)
    				Next
    			Next
    		Else
    			Local $iMatMax = ($iSize*$iSize)/4, $iMatSize = $iSize/2
    			Local $arM1 = _calcMagicSquare($iSize/2)
    			; initial square
    			For $i=0 To 1 Step 1
    				For $j=0 To 1 Step 1
    					Local $iAdd = 0
    					If $i=1 And $j=0 Then $iAdd = $iMatMax*2
    					If $i=0 And $j=1 Then $iAdd = $iMatMax*3
    					If $i=1 And $j=1 Then $iAdd = $iMatMax
    					For $x=0 To $iMatSize-1 Step 1
    						For $y=0 To $iMatSize-1 Step 1
    							$arSquare[$x+($i*$iMatSize)][$y+($j*$iMatSize)] = $arM1[$x][$y] + $iAdd
    						Next
    					Next
    				Next
    			Next
    			If Mod($iMatSize, 4) = 2 Then
    				Local $iMiddleRows = Int($iMatSize/2)+1
    				For $x=$iMiddleRows/2 To $iMatSize-$iMiddleRows/2 Step 1
    					For $y=0 To $iMatSize-1 Step 1
    						_swap($arSquare, $x, $y, $x, $y+$iMatSize)
    					Next
    				Next
    				For $x=$iMiddleRows/2 To $iMatSize-$iMiddleRows/2 Step 1
    					For $y=0 To $iMatSize-1 Step 1
    						_swap($arSquare, $x+$iMatSize, $y, $x+$iMatSize, $y+$iMatSize)
    					Next
    				Next
    			Else
    				Local $iMiddleRows = $iMatSize/2
    				For $x=$iMiddleRows/2 To $iMatSize-$iMiddleRows/2-1 Step 1
    					For $y=0 To $iMatSize-1 Step 1
    						_swap($arSquare, $x, $y, $x, $y+$iMatSize)
    					Next
    				Next
    				For $x=$iMiddleRows/2 To $iMatSize-$iMiddleRows/2-1 Step 1
    					For $y=0 To $iMatSize-1 Step 1
    						_swap($arSquare, $x+$iMatSize, $y, $x+$iMatSize, $y+$iMatSize)
    					Next
    				Next
    			EndIf
    		EndIf
    	Else ; size is odd
    		Local $iN = 1, $x=0, $y=Int($iSize/2), $iLimit = $iSize*$iSize
    		While $iN<=$iLimit
    			If $arSquare[$x][$y]=0 Then
    				$arSquare[$x][$y] = $iN
    				$iN+=1
    				$x -= 1
    				If $x<0 Then $x=$iSize-1
    				$y -= 1
    				If $y<0 Then $y=$iSize-1
    			Else
    				$x = Mod($x+2, $iSize)
    				$y = Mod($y+1, $iSize)
    			EndIf
    		WEnd
    	EndIf
    	Return $arSquare
    EndFunc
    
    Func _swap(ByRef $arSquare, $x1, $y1, $x2, $y2)
    	Local $iTmp = $arSquare[$x1][$y1]
    	$arSquare[$x1][$y1] = $arSquare[$x2][$y2]
    	$arSquare[$x2][$y2] = $iTmp
    EndFunc
    Alles anzeigen

    Referenz:
    Paper mit dem Algorithmus für die Berechnung der Magic Squares: https://www.iupindia.in/910/IJCM_Magic…lgorithms34.pdf

  • array(s) nach daten durchsuchen und zuordnen und damit dann ein neues array anlegen

    • Kanashius
    • 18. April 2025 um 15:08
    Zitat von bankesbusters

    ich habe allerdings noch einige fragen:

    du (und auch viele andere), ja teilweise sogar in den AutoIT hilfe-seiten und den darin enthaltenen beispielen arbeiten unglaublich oft und viel mit 'Func'. ich sehe den vorteil nicht wirklich davon, weil es macht alles nur (meiner meinung nach) unuebersichtlicher. ... du hast dann irgendwo im script "Func _example()" und musst dann erst suchen im script wo die func abgelegt ist (meist ganz unten) und wenn man auf func verzichtet, sieht man den kompletten notwendigen code an der stelle wo er abgearbeitet wird bzw. werden soll. ich sehe den vorteil nicht in der nutzung von funktionen. also wo ist der vorteil?

    jetzt schreibe bitte nicht so etwas wie: "du kannst funktionen mehrmals nutzen an verschiedenen stellen" ... jetzt mal ehrlich, wie oft brauchst du ein und die selbe funktion in einem einzigen script? ich habe eine funktion noch nie ein zweites mal verwendet, oder wenn ich sie ein zweites mal verwendet werden musste, dann musste in der funktion irgend eine kleinigkeit geaendert werden, welches die nutzung der selben funktion ebenfalls unmoeglich machte. gebe mir doch mal bitte ein beispiel wo exakt die gleiche funktion sinnvoll mehrmals genutzt wird in einem script unabhaengig vom user oder usereingaben. geht doch gar nicht, oder doch?

    jedenfalls meine (test)scripte arbeiten alle nach einem schema: wenn dies, dann das und dann jenes und danach etwas anderes. sprich nur wenn prozess 'a' ausgefuehrt wird kann prozess 'b' beginnen usw.

    Naja... es reicht ein Blick in dein Script, warum Funktionen Sinn machen:
    Was ist denn _ArrayDisplay, _ArrayShuffle, ... Genau: Funktionen, die du mehrfach nutzt... wär jetzt doof, wenn du jedesmal den Code von _ArrayShuffle stattdessen dort hinschreiben würdest, oder?

    Spoiler anzeigen

    Der sieht nämlich so aus:

    AutoIt
    Func _ArrayShuffle(ByRef $aArray, $iStart_Row = 0, $iEnd_Row = 0, $iCol = -1)
    
    	; Fisher-Yates algorithm
    
    	If $iStart_Row = Default Then $iStart_Row = 0
    	If $iEnd_Row = Default Then $iEnd_Row = 0
    	If $iCol = Default Then $iCol = -1
    
    	If Not IsArray($aArray) Then Return SetError(1, 0, -1)
    	Local $iDim_1 = UBound($aArray, $UBOUND_ROWS)
    	If $iEnd_Row = 0 Then $iEnd_Row = $iDim_1 - 1
    	If $iStart_Row < 0 Or $iStart_Row > $iDim_1 - 1 Then Return SetError(3, 0, -1)
    	If $iEnd_Row < 1 Or $iEnd_Row > $iDim_1 - 1 Then Return SetError(3, 0, -1)
    	If $iStart_Row > $iEnd_Row Then Return SetError(4, 0, -1)
    
    	Local $vTmp, $iRand
    	Switch UBound($aArray, $UBOUND_DIMENSIONS)
    		Case 1
    			For $i = $iEnd_Row To $iStart_Row + 1 Step -1
    				$iRand = Random($iStart_Row, $i, 1)
    				$vTmp = $aArray[$i]
    				$aArray[$i] = $aArray[$iRand]
    				$aArray[$iRand] = $vTmp
    			Next
    			Return 1
    		Case 2
    			Local $iDim_2 = UBound($aArray, $UBOUND_COLUMNS)
    			If $iCol < -1 Or $iCol > $iDim_2 - 1 Then Return SetError(5, 0, -1)
    			Local $iCol_Start, $iCol_End
    			If $iCol = -1 Then
    				$iCol_Start = 0
    				$iCol_End = $iDim_2 - 1
    			Else
    				$iCol_Start = $iCol
    				$iCol_End = $iCol
    			EndIf
    			For $i = $iEnd_Row To $iStart_Row + 1 Step -1
    				$iRand = Random($iStart_Row, $i, 1)
    				For $j = $iCol_Start To $iCol_End
    					$vTmp = $aArray[$i][$j]
    					$aArray[$i][$j] = $aArray[$iRand][$j]
    					$aArray[$iRand][$j] = $vTmp
    				Next
    			Next
    			Return 1
    		Case Else
    			Return SetError(2, 0, -1)
    	EndSwitch
    
    EndFunc   ;==>_ArrayShuffle
    Alles anzeigen

    Ein weiterer wichtiger Punkt ist nicht nur die Wiederverwendbarkeit (was in meinem Script auch schon mehrfach auftaucht: _readIniToMap wird 2x genutzt, _getRoom 3x,... ) sondern auch die Struktur.
    Je größer ein Programm wird, desto unübersichtlicher wird es. Deshalb gibt es auch so als Richtwert: Wenn ein Codeabschnitt (auch in einer Funktion) mehr als so ca. 30 Zeilen hat sollte er in eine eigene Funktion (gibt natürlich ausnahmen, aber in die Richtung geht es).
    Die Aufgabe wird dadurch in mehrere Abschnitte unterteilt, was das ganze übersichtlicher macht.
    Wenn jemand sich neuen Code von jemand anders anschaut um den zu Verstehen ist es halt übersichtlicher zu sehen:

    Code
    Func _processData()
    	Local $arData = _readData()
    	$arData = _removeDuplicates($arData)
    	$arData = _multiplyDataValues($arData)
    	_saveData($arData)
    EndFunc

    Wo ich abstrahiert erfahre, was gemacht wird. Einlesen->Duplikate entfernen->Daten multiplizieren (als Beispiel für z.B. Zahlen)->Ergebnis speichern.
    Insbesondere, wenn ich später mal was verändern will, weiß ich direkt, in welchen Abschnitt ich gehen muss um ihn mir anzuschauen.
    Ich habe nicht direkt 200 Zeilen Code und muss rausfinden, wo jetzt was passiert, sondern kann direkt zu dem Abschnitt/der Funktion gehen, die ich verändern muss.

    Dazu kommt, dass Funktionen normalerweise auch genutzt werden um bestimmte Aufgaben zu erledigen.
    Am besten ist es dabei, wenn die Funktion alles, was sie braucht als Parameter bekommt und auf keine Globalen Variablen oder ähnliches zugreifen muss.
    Ich kann dann eine Funktion schreiben, die z.B. zwei Matritzen multipliziert und übergebe dort die beiden Matrizen als Parameter.
    Ich habe dann ein geschlossenes System, das genau eine Aufgabe hat: Die beiden Matritzen-Parameter zu multiplizieren und kann genau schauen, wie das passiert und ggf. Fehler korrigieren, ohne das ich das gesamte Script kennen muss, weil ich keine Ahnung hab, wo die Variable denn jetzt herkommt, die 100 Zeilen zuvor erstellt wurde, 10x zwischendurch verändert wird und dann am Ende bei meiner Multiplikation landet.

    Und wenn man immer mit diesem Stil programmiert macht man das natürlich auch in kleinen 50 Zeilen programmen, auch wenn es da nicht unbedingt notwendig wäre.
    Man weiß ja auch nie, ob das Script vielleicht wächst und immer größer erweitert wird und dann steht man am Ende mit 1000 Zeilen durcheinander da ;)

    Ein weiterer Punkt: Es trennt die verschiedenen Variablen voneinandern.
    Variablen sind immer in einem Bereich gülitig. Schreibst du sie einfach in die Datei, gilt sie überall, du kannst also dort z.B. $arData definieren und überall darauf zugreifen.
    Wenn man aber nicht aufpasst kann in größeren Scripten schnell vergessen, dass man den Variable Namen schonmal genutzt hat.
    Dann überschreibt man ausversehen diese Variable und hat dort was komplett anderes drin stehen, als man denkt, was zu Fehlern führen kann, die versteckt sind und deshalb sehr lange brauchen, bis man das Problem findet.
    Nutzt man Funktionen und Lokale Variablen, sind die nur in der Funktion gültig und die Wahrscheinlichkeit für irgendwelche Namens-Konflikte ist erheblich geringer.

  • array(s) nach daten durchsuchen und zuordnen und damit dann ein neues array anlegen

    • Kanashius
    • 17. April 2025 um 20:35

    Doch, die Map ist immernoch die beste Möglichkeit, um den Raum von einer Namen/Monats kombination zu ermitteln.
    Wie du die Namen/Monate speicherst und in welcher Reihenfolge kannst du dir frei aussuchen.

    Wenn du diese Funktion in mein Script von vorher einfügst sollte es das sein, was du willst (wenn ich es jetzt richtig verstanden hab)

    AutoIt
    #include <Array.au3>
    _example2()
    
    Func _example2()
    	Local $mData = _readIniToMap("loesung.ini", "Data")
    	Local $sMonth = 'Januar Februar Maerz April Mai Juni Juli August September Oktober November Dezember'
    	Local $sNames = 'Paul Ursula Robert Marion Peter Nadine Stefan Esther Oliver Evelyn Michael Doris'
    	Local $arMonth = StringSplit($sMonth, " ", BitOR(1, 2))
    	Local $arNames = StringSplit($sNames, " ", BitOR(1, 2))
    	_ArrayShuffle($arMonth, 0,11)
    	_ArrayShuffle($arNames, 0,11)
    	Local $arResult[UBound($arMonth)][3]
    	For $i=0 To UBound($arMonth)-1 Step 1
    		$arResult[$i][0] = $arNames[$i]
    		$arResult[$i][1] = $arMonth[$i]
    		Local $sRoom = _getRoom($mData, $arNames[$i], $arMonth[$i])
    		If $sRoom<>-1 Then $arResult[$i][2] = "Raum "&$sRoom
    	Next
    	_ArrayDisplay($arResult)
    EndFunc
    Alles anzeigen
  • array(s) nach daten durchsuchen und zuordnen und damit dann ein neues array anlegen

    • Kanashius
    • 17. April 2025 um 15:53

    Wenn ich deine Beschreibung richtig verstanden habe, ist das Ziel ein Programm, in dem du den Namen und Monat auswählst und dann den zugehörigen Raum angezeigt bekommst.
    Ich würde in dem Fall nicht mit Arrays, sondern mit Maps arbeiten. Die sind extra dafür da, Daten so abzulegen, dass man mit Schlüsselwörtern (Name/Monat) schnell darauf zugreifen kann:

    AutoIt
    _example()
    
    _startGui()
    
    Func _example()
    	Local $mData = _readIniToMap("loesung.ini", "Data")
    	Local $arNames = ["Paul", "Ursula", "Robert", "Marion", "Peter", "Nadine", "Stefan", "Esther", "Oliver", "Evelyn" ,"Michael", "Doris"]
    	Local $arMonth = ["Januar", "Februar", "Maerz", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"]
    	For $i=0 To UBound($arNames)-1 Step 1
    		For $j=0 To UBound($arMonth)-1 Step 1
    			ConsoleWrite(StringFormat("%-10s is in %-10s in Room: %s", $arNames[$i], $arMonth[$j], _getRoom($mData, $arNames[$i], $arMonth[$j]))&@crlf)
    		Next
    	Next
    EndFunc
    
    Func _getRoom(ByRef $mData, $sName, $sMonth)
    	If MapExists($mData, $sName) Then
    		If MapExists($mData[$sName], $sMonth) Then Return $mData[$sName][$sMonth]
    	EndIf
    	Return -1
    EndFunc
    
    Func _readIniToMap($sFile, $sSection)
    	Local $arSec = IniReadSection($sFile, $sSection)
    	Local $mData[]
    	For $i=1 To UBound($arSec)-1 Step 1
    		;Local $arValue = StringSplit($arSec[$i][1], "|", BitOR(1, 2))
    		;If UBound($arValue)<3 Then ContinueLoop
    		Local $arValue = StringRegExp($arSec[$i][1], "([^|]*)\|(Januar|Februar|Maerz|April|Mai|Juni|Juli|August|September|Oktober|November|Dezember){1}\|Raum(\d+)", 1)
    		If @error Then
    			ConsoleWrite(StringFormat('Error reading IniKey "%s" with Value "%s"', $arSec[$i][0], $arSec[$i][1])&@crlf)
    			ContinueLoop
    		EndIf
    
    		If MapExists($mData, $arValue[0]) Then
    			$mData[$arValue[0]][$arValue[1]] = $arValue[2]
    		Else
    			Local $mEntry[]
    			$mEntry[$arValue[1]] = $arValue[2]
    			$mData[$arValue[0]] = $mEntry
    		EndIf
    	Next
    	Return $mData
    EndFunc
    
    Func _startGui()
    	Local $mData = _readIniToMap("loesung.ini", "Data")
    	Local $arNames = MapKeys($mData)
    	Local $sNames = ""
    	For $i=0 To UBound($arNames)-1 Step 1
    		$sNames&=$arNames[$i]
    		If $i<>UBound($arNames)-1 Then $sNames&="|"
    	Next
    	Local $sMonth = "Januar|Februar|Maerz|April|Mai|Juni|Juli|August|September|Oktober|November|Dezember"
    	Local $iWidth = 300, $iHeight = 100, $iSpace = 10, $iCtrlHeight = 20
    	Local $hGui = GUICreate("Room searcher", $iWidth, $iHeight)
    	Local $idComboNames = GUICtrlCreateCombo("", $iSpace, $iSpace, $iWidth-$iSpace*2, $iCtrlHeight)
    	GUICtrlSetData($idComboNames, $sNames)
    	Local $idComboMonth = GUICtrlCreateCombo("", $iSpace, $iSpace*2+$iCtrlHeight, $iWidth-$iSpace*2, $iCtrlHeight)
    	GUICtrlSetData($idComboMonth, $sMonth)
    	Local $idLabelRoom = GUICtrlCreateLabel("Raum: ", $iSpace, $iSpace*3+$iCtrlHeight*2, $iWidth-$iSpace*2, $iCtrlHeight)
    	GUISetState(@SW_SHOW, $hGui)
    	While True
    		Local $iMsg = GUIGetMsg()
    		Switch $iMsg
    			Case -3
    				Exit
    			Case $idComboNames, $idComboMonth
    				Local $sRoom = _getRoom($mData, GUICtrlRead($idComboNames), GUICtrlRead($idComboMonth))
    				If $sRoom<>-1 Then
    					GUICtrlSetData($idLabelRoom, "Raum: "&$sRoom)
    				Else
    					GUICtrlSetData($idLabelRoom, "Raum: ?")
    				EndIf
    		EndSwitch
    	WEnd
    EndFunc
    Alles anzeigen

    Ich habe hier eine Funktion erstellt, welche die Ini in eine Map einliest. Bei einer Map wird anders als bei einem Array, nicht mit einer Zahl als Index auf einen Wert zugegriffen, sondern stattdessen mit beliebigen Daten. Hier mit dem Namen oder dem Monat.
    Dabei ist das ganze hier in zwei Maps verschachtelt (wie ein 2D-Array).
    Eine Map, bei der man mit dem Namen eine weitere Map bekommt, in der für jeden Monat der Raum steht.

    Code
    Local $mData[]
    $mData["Paul"] = "Something"
    $mData["Mustermann"] = "Something else"
    ; dann kann man mit
    ConsoleWrite("Paul: "&$mData["Paul"]&@crlf)
    ; auf die Daten zugreifen.
    ; in dem Code oben habe ich das ganze beim einlesen der Ini gemacht (_readIniToMap):
    Local $mPersonData[]
    $mPersonData["Januar"] = "Raum 103"
    $mPersonData["Februar"] = "Raum 104"
    $mData["Mustermann"] = $mPersonData
    ; Dann kann so auf die Infos zugegriffen werden:
    ConsoleWrite("Mustermann im Januar: "&$mData["Mustermann"]["Januar"]&@crlf)
    Alles anzeigen

    Das ganze hat auch den Vorteil, dass ich alle Namen aus der $mData Map mit MapKeys($mData) auslesen kann und dann ein Array mit allen Namen aus der Ini-Datei habe, was ich in dem Code nutze um die ComboBox mit Namen zu befüllen.
    Da sich die Monate nicht ändern, musst du das Script also nie anpassen, wenn du eine weitere Person hinzufügst. Es reicht die Datei in der Ini hinzuzufügen.

    Du hast übrigens in der Ini bei einigen Nutzern "Mai" und bei anderen "May" als Monat angegeben, deshalb wird der Raum für manche Nutzer im Mai nicht gefunden.
    Deshalb hab ich mal beim einlesen der Ini das StringSplit mit einem RegExp ausgetauscht. Dadurch wird die Ini geprüft, ob die Eingabe richtig ist, oder ob irgendwo ein Fehler ist und der Fehler ggf. ausgegeben.

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™