2D-Array - Array in Array?

  • naja Array's sind 0-basiert.
    Das heißt das erste Item ist nicht die 1 sondern die 0

    Lies dir mal das Tutorial von BugFix durch ;)

    Achja vorstellen kannst du dir ein 2D array wie eine Excel Tabelle
    $array[x][y]
    Bei diesem array wäre x wie Eine Excel Zeile
    und y wie eine spalte.

    Um jetz genau zu wissen was in einem "Kästchen" steht brauchst du immer Zeile und Spalte.

  • Das Tut "kenne" ich schon. Ich habe es mir angesehen, aber ehrlich gesagt nur teilweise verstanden.
    Das meiste was dort behandelt wird (z. B. Variable oder statische Arrays) werde ich nie brauchen.

    Genau, Schnitel, wie eine Exceltabelle. Das $i benutzen wir dann ja quasi nur deswegen,
    um die Schleife so oft durchlaufen zu lassen, wie die Datei einträge hat?

    Sonst hätte ich das auch in eine Whileschleife packen können, oder sehe ich das falsch?

    Noch zuguterletzt (hoffe ich):

    [autoit]

    Dim $Files2d[$File1[0]][3]

    [/autoit]

    Wozu hast du die Deklariert? Warum [0][3]?

  • Hi!

    Spoiler anzeigen
    [autoit]

    $1D_Array[5] ;-------> 1 Dimension Array mit einer Spalte und 5 Zeilen

    [/autoit] [autoit][/autoit] [autoit]

    $1D_Array[0]; = 1 zeile
    $1D_Array[1]; = 2 zeile
    $1D_Array[2]; = usw.
    $1D_Array[3]
    $1D_Array[4]

    [/autoit] [autoit][/autoit] [autoit]

    $2D_Array[5][3] ;----> 2 Dimension Array mit 3 Spalte und 5 Zeilen

    [/autoit] [autoit][/autoit] [autoit]

    $2D_Array[0][0]; = 1 Zeile 1 Spalte
    $2D_Array[1][1]; = 2 Zeile 2 Spalte
    $2D_Array[2][2]; usw.

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    $1D_Array[0] = 4

    [/autoit] [autoit][/autoit] [autoit]

    $2D_Array[$1D_Array[0]][0]; 5 zeile 1 Spalte weil $1D_Array[0] = 4

    [/autoit]

    LG Kleiner

  • Was ein Array ist weisst du? Ich erkläre das meist anhand von einer Tabellenkalkulation.
    Ein eindimensionales Array ist eine Spalte in der Tabelle, man kann die einzelnen Zellen mit A1, A2, A3 usw ansprechen
    Ein zweidimensionales Array ist ein Tabellenblatt, dort spricht man die einzelnen Zellen über ihre "Koordinaten" an, also Zeile und Spalte: A1, B7,K12
    Ein dreidimensionales Array hast du wenn Tabellenblätter T ins spiel kommen:T1A1,T3B4,T5K12 usw...

    In einer Tabelle findest du die Zellen über Zeilen und Spalten, MEISTENS fängt die Zählweise mit erste Spalte, erste Reihe an...logo, ist ja auch die erste Spalte bzw. Reihe!
    In einem NULLBASIERTEN Array ist der Index der ERSTEN Reihe/Spalte aber keine Eins, sondern eine Null!
    Wenn du nun ein Array dimensionierst, wird das noch besser. Die Funktion Ubound() ist dein Freund!
    Der Wert, der von UBound zurückgegeben wird, ist um 1 größer als der Index des letzten Elements im Array, da die Untergrenze einer Dimension immer 0 ist.

    [autoit]

    dim $a[3]=[1,2,3] ;die 1 hat den Index NULL, also $a[0]=1 $a[1]=2 ...!!!!

    [/autoit][autoit][/autoit][autoit]

    msgbox(0,0,"Das Array hat "&ubound($a)&" Elemente")

    [/autoit][autoit][/autoit][autoit]

    for $index=0 to ubound($a)-1 ;ubound liefert 3 elemente, erste Zahl ist 1 mit dem Index null!!!
    msgbox(0,"Arrayelemente", $index+1 & ". Element= " & $a[$index]) ;beachte index+1 und $a[$i]
    next

    [/autoit]

    genauso sieht das mit 2-dimensionalen Arrays aus.

    Daher ist die Frage

    Zitat

    Wozu hast du die Deklariert? Warum [0][3]?

    schon verkehrt, denn es wird nirgendwo [0][3] deklariert, sondern [$File1[0]][3]...

  • So, ich denke ich habe es verstanden. Muss noch ein wenig rumprobieren.
    Eines erschließt sich mir aber noch nicht völlig:

    [autoit]

    $2D_Array[$1D_Array[0]][0]; 5 zeile 1 Spalte weil $1D_Array[0] = 4

    [/autoit]


    Wieso 5 Zeile Spalte 1? Spalte 1 ist ja noch nachzuvollziehen, aber Zeile 5?

    Noch etwas anderes, aber zum selben Thema:

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>
    #include <File.au3>
    Dim $File1, $File2, $File3
    _FileReadToArray(@ScriptDir & "\eins.ini", $File1)
    _FileReadToArray(@ScriptDir & "\zwei.ini", $File2)
    _FileReadToArray(@ScriptDir & "\drei.ini", $File3)
    Dim $Files2d[$File1[0]][3]
    For $i = 1 To $File1[0]
    $Files2d[$i-1][0] = $File1[$i]
    $Files2d[$i-1][1] = $File2[$i]
    $Files2d[$i-1][2] = $File3[$i]
    Next
    _ArrayDisplay($Files2d)

    [/autoit]


    Ich möchte $aFile2d gerne weiterverwenden. Und zwar in einer
    Schleife. Diese Schleife soll ein anderes 2d-Array, ebenfals mit 3
    Elementen je Spalte, durchsuchen. Dafür muss ich aber ja noch
    die Variable deklarieren. Genügt da

    [autoit]

    Local $aFiles2d

    [/autoit]


    oder übersehe ich da etwas?

    So soll die Schleife aussehen:

    Spoiler anzeigen
    [autoit]

    Local $sOut = ''
    Local $aFiles2d

    [/autoit] [autoit][/autoit] [autoit]

    For $n = 1 To UBound($aFiles2d) -1
    _ArraySearch($anegativliste, $aFiles2d[$n], 1)
    If @error Then
    _ArraySearch($areferenz, $aFiles2d[$n], 1)
    If @error Then
    $sOut &= $aFiles2d[$n] & @CRLF
    EndIf
    EndIf
    Next

    [/autoit] [autoit][/autoit] [autoit]

    Local $fh = FileOpen('log.txt', 1)
    FileWrite($fh, $sOut)
    FileClose($fh)

    [/autoit]


    Theoretisch solls so funktionieren, das _ArraySearch auch für 2d-Arrays gedacht ist.
    Aber den gewünschten Effekt hats nicht. Nichtmal ne Fehlermeldung :whistling:

    Edit: Jetzt sagt er mir "array variable has incorrect number of subscripts or subscript dimension range exceeded"
    in Zeile 5.

    2 Mal editiert, zuletzt von Scritch (1. Oktober 2010 um 15:28)

  • Du musst schon $aFiles2d sagen wieviel Indexes drin sind. Übrigens beginnt ein Array bei 0, d.h. du musst $n auf 0 setzen und nicht 1.

  • Klingt logisch...

    Das von kleiner habe ich inzwischen auch verstanden.

    Aber bei meinem aktuellen Problem komme ich noch nicht weiter,
    auch wenn mir die Problematik jetzt bekannt ist. Irgendwie habe
    ich einen noch nicht gelösten Knoten im Hirn.

    $Files2d soll ja so viele Zeilen bekommen, wie $File1. Und 3 Spalten.
    Müßte es dann nicht auch so aussehen:

    [autoit]

    Local $Files2d[$File1[0]][3]

    [/autoit]


    ?

    Und wenn, wie soll ich das in meine Suchabfrage einbauen? :pinch:

  • Hi!


    Fehler können nur noch auftauchen wenn die Array´s ungleich sind oder aber auch wie in der Hilfe steht, Fehler: 0 und setzt @error @Error: 1 = Fehler beim Öffnen der angegebenen Datei 2 = unmöglich die Datei zu splitten .

    Die abfragen hast du Vergessen! ;)
    Ein möglichkeit um zu umgehen wenn eine Datei kleiner ist habe ich auch als beispiel mit rein genommen!

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>
    #include <File.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Dim $File1, $File2, $File3
    If Not _FileReadToArray(@ScriptDir & "\eins.ini", $File1) Or Not _FileReadToArray(@ScriptDir & "\zwei.ini", $File2) Or Not _FileReadToArray(@ScriptDir & "\drei.ini", $File3) Then; Steht in der Hilfe Beschrieben!
    MsgBox(0, 'Fehler', 'Es sind keine Ini Einträge gefunden!')
    Exit
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    If ($File1[0] <> $File2[0]) Or ($File1[0] <> $File3[0]) Or ($File2[0] <> $File3[0]) Then MsgBox(0, 'Fehler', 'Datein sind ungleich!' & @CR & 'Wir machen weiter!') ; abfrage ob datein gleich groß!

    [/autoit] [autoit][/autoit] [autoit]

    ;Möglichkeit trotzdem weiter zu arbeiten alle auf die gleiche größe zu bringen!
    Dim $UB
    If ($File1[0] > $File2[0]) And ($File1[0] > $File3[0]) Then
    $UB = $File1[0]
    ElseIf ($File2[0] > $File1[0]) And ($File2[0] > $File3[0]) Then
    $UB = $File2[0]
    Else
    $UB = $File3[0]
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ReDim $File1[$UB + 1]
    ReDim $File2[$UB + 1]
    ReDim $File3[$UB + 1]
    Dim $Files2d[$UB][3]

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 1 To $UB
    $Files2d[$i - 1][0] = $File1[$i]
    $Files2d[$i - 1][1] = $File2[$i]
    $Files2d[$i - 1][2] = $File3[$i]
    Next
    _ArrayDisplay($Files2d)

    [/autoit]

    LG Kleiner

  • Ich hab jetzt mal eine kleine Funktion gebastelt mit der man eine Liste von Dateien in ein 2D Array einlesen kann.
    Damit hast du es bisschen leichter ;)

    Spoiler anzeigen
    [autoit]


    #include-once
    #include <File.au3>
    #include <Array.au3>

    [/autoit] [autoit][/autoit] [autoit]

    ;~ #### Testdateien erstellen
    Dim $aFiles[5] = [@TempDir & "\test1.txt", _
    @TempDir & "\test2.txt", _
    @TempDir & "\test3.txt", _
    @TempDir & "\test4.txt", _
    @TempDir & "\test5.txt"]
    For $i = 0 To 4
    For $k = 1 To Random(1, 100, 1)
    FileWrite($aFiles[$i], Chr(Random(33, 127, 1)) & @CRLF)
    Next
    Next
    ;~ #### Ende Testdateien erstellen

    [/autoit] [autoit][/autoit] [autoit]

    $aFilesRead = _FileListReadToArray($aFiles)
    _ArrayDisplay($aFilesRead)

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ; Function Name: _FileListRead2dArray($aFilelist)
    ; Description:: liest eine Liste von Dateien in ein 2D Array ein.
    ; Parameter(s): $aFilelist = Liste von Dateien
    ; Return Value(s): Array mit den eingelesenen Dateien
    ; $ret[x][0] = Anzahl der Zeilen in der Datei x
    ; $ret[x][y] = Zeile y in der Datei x
    ; Author(s): Schnitzel (http://www.autoit.de)
    ;===============================================================================

    [/autoit] [autoit][/autoit] [autoit]

    Func _FileListReadToArray($aFilelist)
    If Not IsArray($aFilelist) Or Not UBound($aFilelist, 0) = 1 Or UBound($aFilelist) <= 1 Then Return SetError(1, 0, "")
    Local $iEnd = Ubound($aFilelist) - 1
    Dim $aRet[1][$iEnd], $aTmp
    For $i = 0 To $iEnd
    If FileExists($aFilelist[$i]) Then
    _FileReadToArray($aFilelist[$i], $aTmp)
    If UBound($aTmp) > UBound($aRet) Then ReDim $aRet[UBound($aTmp)][$iEnd+1]
    For $i2 = 0 To $aTmp[0]
    $aRet[$i2][$i] = $aTmp[$i2]
    Next
    EndIf
    Next
    Return $aRet
    EndFunc

    [/autoit]
  • Juten Morjen,

    gelöst habe ich das Problem immernoch nicht.

    Mithilfe von Kleiner bin ich zwar weitergekommen, aber
    noch nicht bei meinem Ziel angelangt.

    Spoiler anzeigen
    [autoit]

    Local $sOut = ''
    Local $Files2d[$File1[0]][3]


    For $n = 1 To UBound ($Files2d) -1
    _ArraySearch($anegativliste, $Files2d[$n][0], 1)
    If @error Then
    _ArraySearch($areferenz, $Files2d[$n][0], 1)
    If @error Then
    $sOut &= $Files2d[$n][0] & @CRLF
    EndIf
    EndIf
    Next

    Local $fh = FileOpen('log.txt', 1)
    FileWrite($fh, $sOut)
    FileClose($fh)

    [/autoit]


    Das ganze läuft zwar nicht mehr in einen Fehler,
    allerdings wird das Ergebnis auch nicht wie gewollt in
    die log.txt geschrieben.
    Die Arrays werden alle richtig eingelesen ($Files2d,
    $areferenz, $anegativliste)

    Ich weiß einfach nicht, wo der Fehler liegen könnte... :pinch:

  • Hi!


    Wie ich schon in der PN geschrieben habe, genauere angaben sind jetzt gefragt!
    Warum? Denn du hast ein 3 Spalte Array das du dutchläufst, Was steht in der ersten Spalte nach was soll gesucht werden und das mit der zweiten und dritten Spalte.
    Dan kommt es drauf an wie man das 3 Spalten Array durchläuft das beispiel was ich dir gezeigt habe ist ein Ansatz.

    Spoiler anzeigen
    [autoit]

    [autoit]#include <Array.au3>
    #include <Excel.au3>
    #include <File.au3>

    [/autoit]

    [/autoit]

    [autoit]

    [autoit]

    [/autoit]

    [/autoit]

    [autoit]

    [autoit]Local $oreferenz = _ExcelBookOpen(@ScriptDir & "\referenz.xls", 1, False, "", "")
    Local $onegativliste = _ExcelBookOpen(@ScriptDir & "\negativliste.xls", 1, False, "", "")
    Local $areferenz = _ExcelReadSheetToArray($oreferenz)
    Local $anegativliste = _ExcelReadSheetToArray($onegativliste)
    Global $liste = "Q:\bnk\d_global\EDV\Batch\Diensteauswertung\Neu\liste.txt"
    Global $aliste
    _ExcelBookClose($oreferenz)
    _ExcelBookClose($onegativliste)
    _FileReadToArray($liste, $aliste)

    [/autoit]

    [/autoit]

    [autoit]

    [autoit]

    [/autoit]

    [/autoit]

    [autoit]

    [autoit]Sleep(3000)

    [/autoit]

    [/autoit]

    [autoit]

    [autoit]

    [/autoit]

    [/autoit]

    [autoit]

    [autoit]For $z = 1 To UBound($aliste) - 1
    If FileExists("\\" & $aliste[$z] & "\d$\HaSo\" & "\dienstname.ini") Then
    Local $dienstname = "\\" & $aliste[$z] & "\d$\HaSo\" & "dienstname.ini"
    Local $dienststarttyp = "\\" & $aliste[$z] & "\d$\HaSo\" & "dienststarttyp.ini"
    Local $dienststatus = "\\" & $aliste[$z] & "\d$\HaSo\" & "dienststatus.ini"
    Dim $File1, $File2, $File3
    _FileReadToArray($dienstname, $File1)
    _FileReadToArray($dienststarttyp, $File2)
    _FileReadToArray($dienststatus, $File3)
    Dim $Files2d[$File1[0]][3]
    For $i = 1 To $File1[0]
    $Files2d[$i - 1][0] = $File1[$i]
    $Files2d[$i - 1][1] = $File2[$i]
    $Files2d[$i - 1][2] = $File3[$i]
    Next
    Local $sOut = ''
    For $n = 0 To UBound($Files2d) - 1
    For $i = 0 To 2
    _ArraySearch($anegativliste, $Files2d[$n][$i], 1)
    ;_ArraySearch($anegativliste, $Files2d[$n][0], 1)
    If @error Then
    _ArraySearch($areferenz, $Files2d[$n][$i], 1)
    ;_ArraySearch($areferenz, $Files2d[$n][0], 1)
    If @error Then
    $sOut &= $Files2d[$n][$i] & @CRLF
    ;$sOut &= $Files2d[$n][0] & @CRLF
    EndIf
    EndIf
    Next
    Next
    Local $fh = FileOpen('log.txt', 1)
    FileWrite($fh, $sOut)
    FileClose($fh)
    EndIf
    Next

    [/autoit]

    [/autoit]


    Um dir besser helfen zu können werhre eine genaue angabe hilfreich oder du hängst die datein mal bitte in ein Anhang.

    Lg Kleiner

  • So, habe die Dateien, die gebraucht werden, jetzt mal angehängt.
    In der ersten Spalte stehen die Daten aus dem "dienstname.ini"
    In der 2. Spalte die Daten aus "dienststarttyp.ini" in der 3. die
    Daten aus "dienststatus.ini".

    Sinn davon ist es halt, auf einem entfernten Rechner zu schauen, ob keine
    bösartigen Dienste laufen. Gedacht ist es so, dass Zeile für Zeile
    die Einträge aus $Files2d zuerst in $anegativliste gesucht werden.
    Ist der Eintrag dort vorhanden, wird mit der nächsten Zeile aus $Files2d
    weitergemacht. Wird die Zeile z. B. nicht in $anegativliste gefunden,
    wird $areferenz nach dieser gesucht. (Es muss die Zeile genau so vorkommen
    wie es in $Files2d steht, sonst wird die zu suchende Spalte in die log.txt geschrieben)

    1. Spalte 2. Spalte 3. Spalte

    Beispiel:
    Array $Files2d
    1. Zeile: AdminPW Auto Wahr

    Nach dieser Zeile wird jetzt in $anegativliste gesucht,
    ob sie da so drinnensteht.

    Spoiler anzeigen

    Warndienst Disabled FALSCH
    Indexdienst Disabled FALSCH
    Ablagemappe Disabled FALSCH
    (stark gekürzt)

    Steht die erste Zeile nicht in $anegativliste, wird in $areferenz weiter-
    gesucht.

    Spoiler anzeigen

    AdminPW Auto Wahr
    NVIDIA Display Driver Service Auto WAHR
    Microsoft Office Diagnostics Service Manual FALSCH
    Office Source Engine Manual FALSCH
    Plug & Play Auto WAHR
    IPSEC-Dienste Auto WAHR
    Geschützter Speicher Auto WAHR
    (stark gekürzt)


    So, hier ist der Dienst vorhanden. Also, jedes zu suchende
    Element der Zeile 1 aus $Files2d ist so in $areferenz vorhanden.
    Ist dies so, wird nichts weiter mit dieser Zeile gemacht und es wird die
    2. Zeile, alle 3 Elemente genommen.

    2. Zeile:Bösartiger Dienst Auto Wahr

    So wieder wird in $anegativliste gesucht -> Dienst nicht gefunden
    Dienst wird in $areferenz gesucht -> Dienst nicht gefunden.
    Da Dienst nicht gefunden wurde soll die Zeile 2 mit allen
    3 Elementen jetzt in die log.txt geschrieben werden.

    Die .ini's habe ich gekürzt der besseren Übersicht halber
    und des Datenschutzes.

  • Hi!


    So????

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>
    #include <Excel.au3>
    #include <File.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Local $oreferenz = _ExcelBookOpen(@ScriptDir & "\referenz.xlsx", 1, False, "", "")
    Local $onegativliste = _ExcelBookOpen(@ScriptDir & "\negativliste.xlsx", 1, False, "", "")
    Local $areferenz = _ExcelReadSheetToArray($oreferenz)
    Local $anegativliste = _ExcelReadSheetToArray($onegativliste)
    Global $liste = "Q:\bnk\d_global\EDV\Batch\Diensteauswertung\Neu\liste.txt"
    Global $aliste
    _ExcelBookClose($oreferenz)
    _ExcelBookClose($onegativliste)
    _FileReadToArray($liste, $aliste)

    [/autoit] [autoit][/autoit] [autoit]

    ;Sleep(3000)

    [/autoit] [autoit][/autoit] [autoit]

    For $z = 1 To UBound($aliste) - 1
    If FileExists("\\" & $aliste[$z] & "\d$\HaSo\" & "\dienstname.ini") Then
    Local $dienstname = "\\" & $aliste[$z] & "\d$\HaSo\" & "dienstname.ini"
    Local $dienststarttyp = "\\" & $aliste[$z] & "\d$\HaSo\" & "dienststarttyp.ini"
    Local $dienststatus = "\\" & $aliste[$z] & "\d$\HaSo\" & "dienststatus.ini"
    Dim $File1, $File2, $File3
    _FileReadToArray($dienstname, $File1)
    _FileReadToArray($dienststarttyp, $File2)
    _FileReadToArray($dienststatus, $File3)
    Dim $Files2d[$File1[0]][3]
    For $i = 1 To $File1[0]
    $Files2d[$i - 1][0] = $File1[$i]
    $Files2d[$i - 1][1] = $File2[$i]
    $Files2d[$i - 1][2] = $File3[$i]
    Next
    Local $sOut = ''
    For $i = 0 To UBound($Files2d) - 1
    _ArraySearch($anegativliste, $Files2d[$i][0], 0, 0, 1, 1)
    If @error Then
    _ArraySearch($areferenz, $Files2d[$i][0], 0, 0, 1, 1)
    If @error Then
    $sOut &= $Files2d[$i][0] & @TAB
    For $n = 1 To 2
    _ArraySearch($areferenz, $Files2d[$i][$n], 0, 0, 1, $n +1)
    If @error Then
    $sOut &= $Files2d[$i][$n] & @TAB
    EndIf
    Next
    $sOut &= @CRLF
    EndIf
    EndIf
    Next
    ConsoleWrite($sOut & @CRLF)
    Local $fh = FileOpen('log.txt', 1)
    FileWrite($fh, $sOut)
    FileClose($fh)
    EndIf
    Next

    [/autoit]


    LG Kleiner

  • Wenn es Ini's sind, warum nimmst du dann nicht IniReadSection? Wie heißen denn die Sektionen?

  • Moin,

    prinzipiell ist es das Kleiner, aber funktionieren tuts leider nicht ;(
    Das Scripts beendet sich wieder in dem Augenblick, nachdem
    die Daten aus den .xls's ins Array eingelesen wurden.

    Was macht eig. die Schleife hier genau?

    Spoiler anzeigen
    [autoit]

    For $n = 1 To 2
    _ArraySearch($areferenz, $Files2d[$i][$n], 0, 0, 1, $n +1)

    [/autoit]
  • Läuft das von Kleiner nicht? Und wenn es keine Ini's sind, dürfen sie auch nicht so heißen.

  • Nein, tut es leider nicht. Es läuft zwar,
    aber irgendwie wird die Schleife nicht durchlaufen, bzw. nicht so,
    wie es soll. In die Log.txt wird auch nichts geschrieben.

    Wieso dürfen die nicht .ini's heißen? Die werden von einem
    Programm nunmal als .ini zurückgegeben - da kann ich nichts
    für ;)

  • Hi!


    So... Moin, als erstes Frage an dich wie Rufst du die Excel Datein auf ? Den Code von dir steht .xls sind es aber nicht .xlsx sind es jedenfall sagt das deine zip.
    Zu deiner Frage?

    [autoit]

    _ArraySearch($areferenz, $Files2d[$i][$n], 0, 0, 1, $n +1)

    [/autoit]


    Ich habe das so verstanden wenn keiner von $Files2d in der ersten spalte gefunden wurde in den beiden Excel datein soll geprüft werden wahr usw..???????
    Da schaut die func in dem moment in die Excel datei und gib das wieder was da steht. Ist wahrscheinlich nicht richtig oder??

    LG Kleiner